假设我正处于一个函数的中间,LLDB在一个分段错误(内存访问错误)上停止。
是否有可能清除信号,并返回到main,并重新执行一切?(如果代码进行了任何有状态的更改,我希望保留这些更改)。我不是要求在新的会话中终止和重新启动进程。
(不确定这是否有助于澄清问题,但对于那些熟悉Java调试器的人来说,有一个“拖到帧”的概念,它基本上会弹出顶部的x帧,然后重新启动执行)
更新:使用thread return后的详细信息,如下所示。
使用thread return和调整pc确实让我回到了以前的执行点,但是信号没有被清除,所以lldb拒绝继续。
(lldb) target create "test.out"
Current executable set to '/Users/user/test.out' (x86_64).
(lldb) run
Process 89918 launched: '/Users/user/test.out' (x86_64)
before npe
i=0
i=1
i=2
i=3
i=4
Process 89918 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x5)
frame #0: 0x0000000100003ee1 test.out`cause_npe(n=5) at test.c:17:11
14 printf("i=%d\n", i);
15
16 // cause bad mem access here
-> 17 return *(int*)(n);
18 }
19
20 int main ()
Target 0: (test.out) stopped.
(lldb) thread return
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x5)
frame #0: 0x0000000100003f1a test.out`main at test.c:25:3
22 // signal (SIGSEGV, my_handler);
23 printf( "before npe\n");
24 cause_npe(5);
-> 25 printf("recovered after signal\n");
26 return 0;
27 }
(lldb) register write pc `$pc-8`
(lldb) register write pc `$pc-8`
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x5)
* frame #0: 0x0000000100003f0a test.out`main at test.c:23:3
frame #1: 0x00007fff6efa3cc9 libdyld.dylib`start + 1
(lldb) n
Process 89918 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x5)
frame #0: 0x0000000100003f0a test.out`main at test.c:23:3
20 int main ()
21 {
22 // signal (SIGSEGV, my_handler);
-> 23 printf( "before npe\n");
24 cause_npe(5);
25 printf("recovered after signal\n");
26 return 0;
Target 0: (test.out) stopped.test.c代码:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int cause_npe(int n) {
// prints a few lines before the bad mem access
for (int i = 0; i < n; ++i)
printf("i=%d\n", i);
// cause bad mem access here
return *(int*)(n);
}
int main () {
printf( "before npe\n");
cause_npe(5);
printf("recovered after signal\n");
return 0;
}发布于 2021-02-18 18:52:07
lldb有一个thread return命令,它从堆栈中弹出帧。这将回到一个点后,调用是活跃的堆栈帧,你返回,所以你必须使用thread jump,使pc回到调用站点。
这样做将使内存状态保持不变,因此从全局变量或静态变量访问的任何内容都将保留其状态。thread return是相当残忍的力量,然而,它盲目地展开堆栈,它不试图模仿异常抛出的所有清理。因此,任何堆栈分配的对象都将被搁浅,而不是被销毁,如果您返回到版本之后,您可能会得到过多保留的对象。
此外,如果程序是多线程的,则必须注意其他线程尚未从正在展开的线程中传递堆栈分配对象。当您重新执行时,这些线程将被重新分配,因此这两个线程将有不同的副本。
无论如何,尽管可能,这不是一个通用的技术,如果你使用它,你想要怀疑你看到了什么,或者你很可能花时间去寻找展开过程中的工件,而不是学习任何有用的东西。
https://stackoverflow.com/questions/66254480
复制相似问题