gdb weird backtrace

混江龙づ霸主 提交于 2019-11-30 09:03:18

It's a stack overrun.

#4  0x2054454e in ?? ()

That looks like text, " TEN" or "NET "

#5  0x20524c43 in ?? ()

" RLC" or "CLR "

And so on.

Treat the addresses as if they were text - see if you can identify where this text overwrites your stack.

Your stack trace is actually very easy to understand:

  • You got SIGSEGV somewhere,
  • Your signal handler did whatever it does, then called abort()
  • Which issued raise(2) system call, by calling __unified_syscall()

The reason you get no stack trace in GDB is that

  • __unified_syscall is implemented in assembly, and
  • does not use frame pointer, and
  • does not have proper cfi directives to describe how to unwind from it.

I would consider this a bug in dietlibc, quite easy to fix, actually. See if this (untested) patch fixes it for you:

--- dietlibc-0.31/i386/unified.S.orig   2011-03-13 10:16:23.000000000 -0700
+++ dietlibc-0.31/i386/unified.S    2011-03-13 10:21:32.000000000 -0700
@@ -31,8 +31,14 @@ __unified_syscall:
    movzbl  %al, %eax
 .L1:
    push    %edi
+        cfi_adjust_cfa_offset (4)
+        cfi_rel_offset (edi, 0)
    push    %esi
+        cfi_adjust_cfa_offset (4)
+        cfi_rel_offset (esi, 0)
    push    %ebx
+        cfi_adjust_cfa_offset (4)
+        cfi_rel_offset (ebx, 0)
    movl    %esp,%edi
    /* we use movl instead of pop because otherwise a signal would
       destroy the stack frame and crash the program, although it
@@ -61,8 +67,11 @@ __unified_syscall:
 #endif
 .Lnoerror:
    pop %ebx
+        cfi_adjust_cfa_offset (-4)
    pop %esi
+        cfi_adjust_cfa_offset (-4)
    pop %edi
+        cfi_adjust_cfa_offset (-4)

 /* here we go and "reuse" the return for weak-void functions */
 #include "dietuglyweaks.h"

If you can't rebuild dietlibc, or if the patch is incorrect, you may still be able to analyze the stack trace better. As far as I can tell, __unified_syscall does not touch %ebp. So you might be able to get a reasonable stack trace by doing this:

define xbt
  set $xbp = (void **)$arg0
  while 1
    x/2a $xbp
    set $xbp = (void **)$xbp[0]
  end
end

xbt $ebp

Note: if the xbt works, it is likely to go into the weeds around the SIGSEGV signal frame (that frame does not use frame pointer either). This may result in complete garbage, or in a skipped frame or two (which would be exactly the frames where SIGSEGV happened).

So you really are much better off getting proper unwind descriptors into dietlibc.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!