问题描述
我正在根据sigaction/sa_handler机制在Mac OSX上编写程序.运行用户的代码段,并随时准备捕获信号/异常.该程序工作正常,但问题是我无法使用lldb对其进行调试. lldb似乎无法忽略任何异常,即使我设置了
I am writing a program on Mac OSX depending on the sigaction/sa_handler mechanism. Run a code snippet from user and get ready to catch signals/exceptions at any time. The program works fine, but the problem is I can't debug it with lldb. lldb seems not being able to ignore any exceptions even I set
proc hand -p true -s false SIGSEGV
proc hand -p true -s false SIGBUS
控制流在触发异常的指令处停止,即使我尝试了命令c
,它也不会跳转到我先前安装的sa_handler.输出为:
The control flow stops at the instruction that triggers the exception and does not jump to the sa_handler I installed earlier even I tried command c
. The output was:
Process 764 stopped
* thread #2: tid = 0xf140, 0x00000001000b8000, stop reason = EXC_BAD_ACCESS (code=2, address=0x1000b8000)
如何使lldb忽略异常/信号并让程序的sa_handler进行工作?
How do I make lldb ignore the exception/signal and let the sa_handler of the program do its work?
示例代码
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
static void handler(int signo, siginfo_t *sigaction, void *context)
{
printf("in handler.\n");
signal(signo, SIG_DFL);
}
static void gen_exception()
{
printf("gen_exception in.\n");
*(int *)0 = 0;
printf("gen_exception out.\n");
}
void *gen_exception_thread(void *parg)
{
gen_exception();
return 0;
}
int main()
{
struct sigaction sa;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
if(sigaction(/*SIGBUS*/SIGSEGV, &sa, NULL) == -1) {
printf("sigaction fails.\n");
return 0;
}
pthread_t id;
pthread_create(&id, NULL, gen_exception_thread, NULL);
pthread_join(id, NULL);
return 0;
}
推荐答案
我在最近的项目中需要此功能,因此我只是构建了自己的LLDB.我在tools/debugserver/source/MacOSX/MachTask.mm
中的
I needed this in a recent project, so I just built my own LLDB. I patched a line in tools/debugserver/source/MacOSX/MachTask.mm
from
err = ::task_set_exception_ports (task, m_exc_port_info.mask, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
到
err = ::task_set_exception_ports (task, m_exc_port_info.mask & ~EXC_MASK_BAD_ACCESS, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
导致调试服务器无法捕获EXC_BAD_ACCESS
异常.现在,我的自定义LLDB可以正常工作:它仍然捕获SIGSEGV
和SIGBUS
,但是在面对EXC_BAD_ACCESS
时不再进入傻的无限循环.在先前致命的信号上设置process handle
选项也可以正常工作,现在我可以不受惩罚地调试SEGV处理程序.
which causes the debugserver to be unable to catch EXC_BAD_ACCESS
exceptions. Now, my custom LLDB works just fine: it still catches SIGSEGV
and SIGBUS
but no longer enters a silly infinite loop when faced with EXC_BAD_ACCESS
. Setting process handle
options on the previously-fatal signals works fine too, and I can now debug SEGV handlers with impunity.
Apple确实应该在LLDB中将此选项作为一个选项...似乎对他们来说很容易解决.
Apple really ought to make this an option in LLDB...seems like a really easy fix for them.
这篇关于如何使lldb忽略EXC_BAD_ACCESS异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!