lldb在SIGSEGV时中断程序

9

作为来自Linux/gdb世界的人,gdb默认在检测到SEGV时中断程序的执行,然后由默认处理程序清理进程。

lldb如何实现类似的技巧?目前,该进程只是退出,从而无法查询回溯等信息。


编辑proccess handle -p true -n true -s true尝试过了,但没有结果 :(

(lldb) process handle -p true -n true -s true SIGSEGV
NAME        PASS   STOP   NOTIFY
==========  =====  =====  ======
SIGSEGV     true   true   true 
(lldb) run
Process 97630 launched: '/Volumes/My Finder Extensions 1/My_Daemon.app/Contents/PlugIns/My_ShellExt.appex/Contents/MacOS/My_ShellExt' (x86_64)
Process 97630 exited with status = 0 (0x00000000) Terminated due to signal 9

编辑:更多信息:

(lldb) bt all
error: invalid thread

我怀疑lldb不太适用于损坏的堆栈 - 我正在尝试追踪涉及_NSExtensionMain入口点或与之相关的问题。


1
你确定你的程序收到了SIGSEGV信号吗?信号9是SIGKILL,除非可能有一些Mach特定的方法来捕获它,否则调试器无法捕获它。 - Mark Plotnick
1
这里发生了一些奇怪的事情。我们得到了进程的退出状态(0),所以它实际上是正常退出的。不确定为什么我们还认为它收到了信号9。顺便说一下,如果您正在调试程序并且它收到了SIGKILL,它将在调试器中停止并显示SIGKILL。调试器可以捕获SIGKILL,但无法抑制它们。 - Jim Ingham
你能否尝试一下逐步调试?我认为你的程序可能覆盖了一部分“敏感数据”,比如IVT或PCB,这可能是你无法执行“回溯”的原因。 - VivienG
1
实际上,问题似乎源于有些混乱的堆栈情况(错误非常早地出现在Mach-O入口点),是函数序言导致了内存访问违规 - 甚至在应用程序的默认处理程序安装之前。因此 - 退出0。 - qdot
2个回答

5

根据这里的说明,在lldb中应输入process handle SIGSEGV --notify true --pass true --stop true

(lldb)process handle SIGSEGV --notify true --pass true --stop true


听起来很合理,但实际上在我的情况下不起作用,不知道为什么。 - qdot
1
你是否在远程目标上运行你的应用程序?当我通过JTAG调试C应用程序到远程目标时,我遇到了类似的问题。我不得不使用OpenOCD最终得到我所需的结果。但我想这不是你的情况,对吧? - VivienG
本地目标,有些奇怪的应用程序入口(试图编写一个应用程序扩展,主要使用 C++ 重新使用 Linux/Win32 代码) - qdot
当您的应用程序崩溃时,您可以输入“bt all”并将结果作为编辑放入主要帖子中。 - VivienG

0

我写了一个快速测试程序,

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void handler (int in)
{
    puts ("signal received");
}

int main ()
{
    signal (SIGSEGV, handler);    
    kill (getpid (), SIGSEGV);
    return 0;
}

然后我尝试调试它,告诉lldb在SIGSEGV处停止:

(lldb) br s -n main
(lldb) r
(lldb) pr h -p true -n true -s true SIGSEGV
NAME        PASS   STOP   NOTIFY
==========  =====  =====  ======
SIGSEGV     true   true   true 
(lldb) c
Process 5024 resuming
Process 5024 stopped

(lldb) bt
* thread #1: tid = 0x19d6ae, 0x00007fff8f27fc7e libsystem_kernel.dylib`__kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSEGV
  * #0: 0x00007fff8f27fc7e libsystem_kernel.dylib`__kill + 10
    #1: 0x0000000100000f25 a.out`main + 53 at a.c:13
    #2: 0x00007fff8c0e65c9 libdyld.dylib`start + 1
(lldb) c
Process 5024 resuming
signal received
Process 5024 exited with status = 0 (0x00000000) 
(lldb) 

好的,看起来就像我们预期的那样。我还可以要求lldb在不停止的情况下直接转发信号:

(lldb) br s -n main
(lldb) r
(lldb) pr h -p true -n true -s false SIGSEGV
NAME        PASS   STOP   NOTIFY
==========  =====  =====  ======
SIGSEGV     true   false  true 
(lldb) c
Process 5055 resuming
Process 5055 stopped and restarted: thread 1 received signal: SIGSEGV
signal received
Process 5055 exited with status = 0 (0x00000000) 
(lldb) 

看起来它做了我们想要的事情:lldb通知我们收到了信号,然后将其发送到程序。

这是在安装了Xcode 6的Mac OS X上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接