gpt4 book ai didi

mips - 在SIGSEGV上显示_Unwind_Backtrace

转载 作者:行者123 更新时间:2023-12-05 00:54:40 24 4
gpt4 key购买 nike

在mips平台上,我正在尝试让Unwind工作。当前,如果我手动发出print_trace,则堆栈跟踪正确显示如下:


backtrace_helper 0x4b6958

backtrace_helper 0x4b6ab4

backtrace_helper 0x2ac2f628

获得3个堆叠帧。

./v(print_trace+0x38)[0x4b6958]

./v(main+0x90)[0x4b6ab4]

/lib/libc.so.0(__uClibc_main+0x24c)[0x2ac2f628]


但是,当发生SIGSEGV时,堆栈跟踪不会显示正确的函数调用顺序。


backtrace_helper 0x4b7a74

backtrace_helper 0x2ab9b84c

获得2个堆叠帧。

./v(getLineIDByPhyIdx+0x3d8)[0x4b7a74]

/lib/libpthread.so.0(__new_sem_post+0x2c8)[0x2ab9b84c]


我正在使用-g -fexceptions -rdynamic进行编译。我也看到了How to generate a stacktrace when my gcc C++ app crashes,其中第二个答案提到了错误的地址,但是当我像他一样设置时,却只改变了第二个帧,其余的都一样,代码片段如下:

caller_address = (void *) uc->uc_mcontext.gregs[30]; // Frame pointer (from wikipedia here)  

fprintf(stderr, "signal %d (%s), address is %p from %p\n",
sig_num, strsignal(sig_num), info->si_addr,
(void *)caller_address);

size = backtrace(array, 50);

/* overwrite sigaction with caller's address */
array[1] = caller_address;

messages = backtrace_symbols(array, size);




码:

int main(int argc, char *argv[]) {
registerSignalHandler(signalHandler);

print_trace();

{
// Seg Fault
int *p = NULL;
*p = 54;
}
}

void print_trace(void) {
void *array[10];
size_t size;
char **strings;
size_t i;

/* Get the address at the time the signal was raised from the EIP (x86) */
size = backtrace(array, 10);
strings = backtrace_symbols(array, size);

printf("Obtained %zd stack frames.\n", size);

for (i = 0; i < size; i++)
printf("%s\n", strings[i]);

free(strings);
}



static _Unwind_Reason_Code
backtrace_helper (struct _Unwind_Context *ctx, void *a)
{
struct trace_arg *arg = a;

assert (unwind_getip != NULL);

/* We are first called with address in the __backtrace function. Skip it. */
if (arg->cnt != -1) {
arg->array[arg->cnt] = (void *) unwind_getip (ctx);
printf("backtrace_helper %p \n", arg->array[arg->cnt]);
}
if (++arg->cnt == arg->size)
return _URC_END_OF_STACK;
return _URC_NO_REASON;
}

/*
* Perform stack unwinding by using the _Unwind_Backtrace.
*
* User application that wants to use backtrace needs to be
* compiled with -fexceptions option and -rdynamic to get full
* symbols printed.
*/
int backtrace (void **array, int size)
{
struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };

if (unwind_backtrace == NULL)
backtrace_init();

if (size >= 1)
unwind_backtrace (backtrace_helper, &arg);

return arg.cnt != -1 ? arg.cnt : 0;
}


void signalHandler( int sig, siginfo_t* siginfo, void* notused)
{
/* Print out the signal info */
signalInfo(sig, siginfo);

switch (sig) {
case SIGSEGV:
{
print_trace();
abort();
}
}
}

最佳答案

帧指针实际上从未在MIPS上使用,并且在不深入了解符号的情况下获取回溯就需要一些启发。

典型的方法是分析当前指令指针之前的代码,并尝试查找调整SP的函数序言。使用该信息,可以知道前一帧的位置,等等。

有关这些血腥细节,请参见以下幻灯片:
http://elinux.org/images/0/07/Intricacies_of_a_MIPS_Stack_Backtrace_Implementation.pdf

关于mips - 在SIGSEGV上显示_Unwind_Backtrace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6282627/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com