如何使用SIGSEGV的信号处理程序调试程序

时间:2022-02-08 22:54:05

I am writing a plugin for a application, occasionally a SIGSEGV would be throw out. However, the application catches the signal SIGSEGV. In other word, The plugin is a dynamical library. The error occurs in my plugin and dynamical library. But the applcation handle the sSIGSEGV and exit normally. So, it is quite difficult for me to debug and get the backtrace of all stack frames. Any idea?

我正在为一个应用程序编写一个插件,偶尔会抛出一个SIGSEGV。但是,应用程序捕获信号SIGSEGV。换句话说,插件是一个动态库。错误发生在我的插件和动态库中。但applcation处理sSIGSEGV并正常退出。因此,我很难调试并获得所有堆栈帧的回溯。任何想法?

Currently I am using gdb as debug tool.

目前我使用gdb作为调试工具。

2 个解决方案

#1


7  

GDB will catch SIGSEGV before the application does.

GDB将在应用程序执行之前捕获SIGSEGV。

What you described in comment to Logan's answer makes no sense.

你在评论洛根的答案中描述的内容毫无意义。

I suspect what's really happening is that the application creates a new process, and only gets SIGSEGV in that other process, not the one you attached GDB to.

我怀疑实际发生的是应用程序创建了一个新进程,并且只在另一个进程中获取SIGSEGV,而不是将GDB附加到该进程的进程。

The following commands may be useful if my guess is correct:

如果我的猜测正确,以下命令可能会有用:

(gdb) catch fork
(gdb) catch vfork
(gdb) set follow-fork-mode child

You might also want to edit and expand your question:

您可能还想编辑和扩展您的问题:

  • how do you know there is a SIGSEGV to begin with?
  • 你怎么知道有一个SIGSEGV开头?

  • Posting a log of your interaction with GDB may also prove useful.
  • 发布与GDB交互的日志也可能有用。

#2


4  

Even if the program traps SIGSEGV, gdb should still get it first and give you an opportunity to debug the program. Have you done something like

即使程序陷入SIGSEGV,gdb仍应首先获取它,并为您提供调试程序的机会。你做过类似的事吗?

 handle SIGSEGV nostop

in GDB? If so that could be why it is not stopping.

在GDB?如果是这样,那可能就是它没有停止的原因。

Are you sure that a segfault is actually occurring? Can you duplicate this behavior with another program, or by intentionally causing a segmentation violation?

你确定段错误确实发生了吗?您可以使用其他程序复制此行为,还是故意导致分段违规?

For example:

$ cat sig.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void handle(int n)
{
        puts("Bail");
        exit(1);
}

int main()
{
        signal(SIGSEGV, handle);
        int *pi = 0;
        *pi = 10;
        return 0;
}
$ gcc -g sig.c
$ ./a.out
Bail
$ gdb ./a.out
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) run
Starting program: /home/elcapaldo/a.out

Program received signal SIGSEGV, Segmentation fault.
0x08048421 in main () at sig.c:15
15              *pi = 10;
(gdb) where
#0  0x08048421 in main () at sig.c:15
(gdb) c
Continuing.
Bail

Program exited with code 01.
(gdb) q

#1


7  

GDB will catch SIGSEGV before the application does.

GDB将在应用程序执行之前捕获SIGSEGV。

What you described in comment to Logan's answer makes no sense.

你在评论洛根的答案中描述的内容毫无意义。

I suspect what's really happening is that the application creates a new process, and only gets SIGSEGV in that other process, not the one you attached GDB to.

我怀疑实际发生的是应用程序创建了一个新进程,并且只在另一个进程中获取SIGSEGV,而不是将GDB附加到该进程的进程。

The following commands may be useful if my guess is correct:

如果我的猜测正确,以下命令可能会有用:

(gdb) catch fork
(gdb) catch vfork
(gdb) set follow-fork-mode child

You might also want to edit and expand your question:

您可能还想编辑和扩展您的问题:

  • how do you know there is a SIGSEGV to begin with?
  • 你怎么知道有一个SIGSEGV开头?

  • Posting a log of your interaction with GDB may also prove useful.
  • 发布与GDB交互的日志也可能有用。

#2


4  

Even if the program traps SIGSEGV, gdb should still get it first and give you an opportunity to debug the program. Have you done something like

即使程序陷入SIGSEGV,gdb仍应首先获取它,并为您提供调试程序的机会。你做过类似的事吗?

 handle SIGSEGV nostop

in GDB? If so that could be why it is not stopping.

在GDB?如果是这样,那可能就是它没有停止的原因。

Are you sure that a segfault is actually occurring? Can you duplicate this behavior with another program, or by intentionally causing a segmentation violation?

你确定段错误确实发生了吗?您可以使用其他程序复制此行为,还是故意导致分段违规?

For example:

$ cat sig.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void handle(int n)
{
        puts("Bail");
        exit(1);
}

int main()
{
        signal(SIGSEGV, handle);
        int *pi = 0;
        *pi = 10;
        return 0;
}
$ gcc -g sig.c
$ ./a.out
Bail
$ gdb ./a.out
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) run
Starting program: /home/elcapaldo/a.out

Program received signal SIGSEGV, Segmentation fault.
0x08048421 in main () at sig.c:15
15              *pi = 10;
(gdb) where
#0  0x08048421 in main () at sig.c:15
(gdb) c
Continuing.
Bail

Program exited with code 01.
(gdb) q