它在
http://sourceware.org/ml/gdb/2007-06/msg00360.html之前提到过.
但似乎没有人真正实现过这种想法.
实现这个有什么障碍吗?
但似乎没有人真正实现过这种想法.
实现这个有什么障碍吗?
我的要求如下:
>能够插入任何精灵二进制可执行文件(例如,使用LD_PRELOAD)
>二进制文件可能是多线程可执行文件
>二进制文件可以链接到包含main函数的库
>这应该适用于x86以外的各种cpu架构(至少MIPS,ARM,PPC)
所以,如果已经有这样的解决方案,我想要一个链接,但如果还没有,我想知道为什么它还没有作为一个轮子实现.
可能只是没有人不需要它……但我认为这对于准备标准非常有用.
除了将代码放在一起之外,还需要任何技术或政治问题.
解决方法
似乎并不太难.
$./a.out Caught signal at 0x400966: Segmentation fault Segmentation fault $GDB_COMM=:1024 ./a.out Caught signal at 0x400966: Segmentation fault Attached; pid = 2369 Listening on port 1024
$gdb ./a.out Reading symbols from /home/me/a.out...done. (gdb) target remote :1024 Remote debugging using :1024
#define _XOPEN_SOURCE 500 #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> static char *gdb_comm; static void segv_handler(int sig,siginfo_t *si,void *uc) { pid_t child; char msg[84],pid[20]; char *const argv[] = {"gdbserver",gdb_comm,"--attach",pid,NULL}; sprintf(msg,"Caught signal at %p",si->si_addr); psignal(si->si_signo,msg); if (gdb_comm && *gdb_comm) { switch ((child = fork())) { case 0: sprintf(pid,"%ld",(long)getppid()); execvp(argv[0],argv); perror("Failed to start gdbserver"); _exit(-1); case -1: perror("Failed to fork"); default: waitpid(child,NULL,0); break; } } } int main(int argc,char **argv) { static struct sigaction segv_action = { .sa_sigaction = segv_handler,.sa_flags = SA_RESETHAND | SA_SIGINFO,}; gdb_comm = getenv("GDB_COMM"); sigaction(SIGILL,&segv_action,NULL); sigaction(SIGFPE,NULL); sigaction(SIGSEGV,NULL); sigaction(SIGBUS,NULL); *(int *)main = 0; return 0; }