【问题标题】:lldb break upon SIGSEGVlldb 在 SIGSEGV 上中断
【发布时间】:2014-12-19 05:01:11
【问题描述】:

来自 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 入口点的问题,或者从那里开始的一些事情。

【问题讨论】:

  • 您确定您的程序正在获得 SIGSEGV 吗?信号 9 是 SIGKILL,调试器无法捕捉到它(除非可能有一些特定于 Mach 的方法)。
  • 这里发生了一些奇怪的事情。我们得到了进程的退出状态(0),所以它实际上正常退出了。不知道为什么我们也认为它得到了一个信号 9。顺便说一句,如果你正在调试一个程序并且它得到一个 SIGKILL,它将在调试器中停止,并带有 SIGKILL。调试器可以捕获 SIGKILL,它不能做的是抑制它们。
  • 您可以尝试逐步调试吗?我认为您的程序会覆盖 IVT 或 PCB 等“敏感数据”的一部分,这可能就是您无法执行 backtrace 的原因。
  • 实际上,问题似乎是由于堆栈情况有些混乱(该错误在 Mach-O 入口点很早就出现了),是的,它是导致内存访问冲突的函数前导码 -甚至在安装应用程序的默认处理程序之前。因此 - 出口 0。

标签: debugging gdb lldb segmentation-fault


【解决方案1】:

你应该根据this在lldb上输入process handle SIGSEGV --notify true --pass true --stop true

(lldb)进程句柄 SIGSEGV --notify true --pass true --stop true

【讨论】:

  • 这听起来很合理 - 但实际上对我来说不起作用,不知道为什么。
  • 您是否在远程目标上运行您的应用程序?当我通过 JTAG 将 C 应用程序调试到远程目标时,我遇到了类似的问题。我必须使用 OpenOCD 才能最终得到我需要的东西。但我不认为这是你的情况,对吧?
  • 本地目标,有点奇怪的应用程序入口点(尝试主要用 C++ 编写应用程序扩展以重用 Linux/Win32 代码)
  • 当您的应用死机时,您可以输入bt all 并将结果作为编辑内容放到您的主帖中。
【解决方案2】:

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

#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 上。

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 2014-08-29
    • 2012-11-10
    • 2014-07-06
    • 2019-12-18
    • 2019-06-03
    • 2018-09-07
    • 2014-09-03
    • 1970-01-01
    相关资源
    最近更新 更多