首页 > C/C++ > 源代码中插入断点以方便调试

源代码中插入断点以方便调试

主要利用中断int 3:

#define DEBUG_BREAK do {asm volatile ("int3"); } while(0)

但是, 在没有attach调试器的情况下直接调用int3触发SIGTRAP会导致进程退出, 因此需要再这之前检查进程是否已经被调试器attach。
1,在OSX/BSD上可以使用sysctl来检测;
2,在Linux中可以通过读取/proc/self/status文件的TracerPid字段来检查进程是否被attach (如果未被attach, 则TracerPid:0);
3, Windows上则直接有IsDebuggerPresent API可以使用。

下面完整的代码示例了OSX下如何使用源代码中的断点:

#include <errno.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#define DEBUG_BREAK do {asm volatile ("int3"); } while(0)

bool BeingDebugged() {
  int mib[] = {
    CTL_KERN,
    KERN_PROC,
    KERN_PROC_PID,
    getpid()
  };

  struct kinfo_proc info;
  size_t info_size = sizeof(info);

  int sysctl_result = sysctl(mib, 4, &info, &info_size, NULL, 0);
  if (sysctl_result != 0) {
    perror("sysctl failed\n");
    printf("sysctl failed: %d\n", errno);
    return false;
  }

  bool being_debugged = (info.kp_proc.p_flag & P_TRACED) != 0;

  return being_debugged;
}

int WaitForDebugger() {

  while(true) {
    if (BeingDebugged() ) {
      printf("Process is debugged\n");
      DEBUG_BREAK;
      return 1;
    }

    usleep(1);
  }
  return 0;
}

int main(int argc, char** argv)
{
  WaitForDebugger();
  printf("return from WaitForDebugger");

  // other code
  while(true) {
    printf("the functional code\n");
    usleep(1000);
  }
}


分类:C/C++
  1. 还没有评论。
  1. No trackbacks yet.

留下评论