GDB странный след - PullRequest
       22

GDB странный след

10 голосов
/ 13 марта 2011

Моя программа статически скомпилирована при помощи dietlibc.Он скомпилирован в ubuntu x64 (скомпилирован для x86 с использованием флага -m32) и работает на centos x86.

Скомпилированный размер составляет всего около 100 КБ.Я компилирую его с -ggdb3 и без флагов оптимизации.

Моя программа использует signal.h для обработки сигнала SIGSEGV, а затем вызывает abort ().

Программа работает без проблем в течение нескольких дней, но иногда. ошибка сегментацияЭто когда я получаю странные следы, которые я не понимаю:

username@ubuntu:~/Desktop$ gdb -c core.28569 program-name
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=i386-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from program-name...done.
[New Thread 28569]
Core was generated by `program-name'.
Program terminated with signal 6, Aborted.
#0  0x00914410 in __kernel_vsyscall ()
Setting up the environment for debugging gdb.
Function "internal_error" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
Function "info_command" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
.gdbinit:8: Error in sourced command file:
Argument required (one or more breakpoint numbers).
(gdb) bt
#0  0x00914410 in __kernel_vsyscall ()
During symbol reading, incomplete CFI data; unspecified registers (e.g., eax) at 0x914411.
#1  0x0804d7f4 in __unified_syscall ()
#2  0xbf8966c0 in ?? ()
#3  
#4  0x2054454e in ?? ()
#5  0x20524c43 in ?? ()
#6  0x2e352e33 in ?? ()
#7  0x32373033 in ?? ()
#8  0x2e203b39 in ?? ()
#9  0x2054454e in ?? ()
#10 0x20524c43 in ?? ()
#11 0x2e302e33 in ?? ()
#12 0x32373033 in ?? ()
#13 0x4d203b39 in ?? ()
#14 0x61696465 in ?? ()
#15 0x6e654320 in ?? ()
#16 0x20726574 in ?? ()
#17 0x36204350 in ?? ()
#18 0x203b302e in ?? ()
#19 0x54454e2e in ?? ()
#20 0x43302e34 in ?? ()
#21 0x00000029 in ?? ()
#22 0xbf8989a8 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) bt full
#0  0x00914410 in __kernel_vsyscall ()
No symbol table info available.
#1  0x0804d7f4 in __unified_syscall ()
No symbol table info available.
#2  0xbf8966c0 in ?? ()
No symbol table info available.
#3  
No symbol table info available.
#4  0x2054454e in ?? ()
No symbol table info available.
#5  0x20524c43 in ?? ()
No symbol table info available.
#6  0x2e352e33 in ?? ()
No symbol table info available.
#7  0x32373033 in ?? ()
No symbol table info available.
#8  0x2e203b39 in ?? ()
No symbol table info available.
#9  0x2054454e in ?? ()
No symbol table info available.
#10 0x20524c43 in ?? ()
No symbol table info available.
#11 0x2e302e33 in ?? ()
No symbol table info available.
#12 0x32373033 in ?? ()
No symbol table info available.
#13 0x4d203b39 in ?? ()
No symbol table info available.
#14 0x61696465 in ?? ()
No symbol table info available.
#15 0x6e654320 in ?? ()
No symbol table info available.
#16 0x20726574 in ?? ()
No symbol table info available.
#17 0x36204350 in ?? ()
No symbol table info available.
#18 0x203b302e in ?? ()
No symbol table info available.
#19 0x54454e2e in ?? ()
No symbol table info available.
#20 0x43302e34 in ?? ()
No symbol table info available.
#21 0x00000029 in ?? ()
No symbol table info available.
#22 0xbf8989a8 in ?? ()
No symbol table info available.
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) quit

Ответы [ 2 ]

16 голосов
/ 13 марта 2011

Это переполнение стека.

#4  0x2054454e in ?? ()

Это похоже на текст, "TEN" или "NET"

#5  0x20524c43 in ?? ()

"RLC" или "CLR"

И т. Д.

Обращайтесь с адресами, как если бы они были текстовыми - посмотрите, сможете ли вы определить, где этот текст перезаписывает ваш стек.

6 голосов
/ 13 марта 2011

Ваша трассировка стека на самом деле очень проста для понимания:

  • Вы где-то получили SIGSEGV,
  • Ваш обработчик сигналов сделал все, что он делает, затем вызвал abort()
  • который произвел raise(2) системный вызов, вызвав __unified_syscall()

Причина, по которой вы не получаете трассировки стека в GDB, заключается в том, что

  • __unified_syscall реализован всборка, и
  • не использует указатель фрейма, а
  • не имеет надлежащих cfi директив для описания того, как отмотать его.

Я бы рассмотрелэто ошибка в dietlibc, довольно легко исправить на самом деле.Посмотрите, исправит ли вас этот (непроверенный) патч:

--- 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"

Если вы не можете перестроить dietlibc или если патч неправильный, вы все равно сможете лучше проанализировать трассировку стека.Насколько я могу сказать, __unified_syscall не касается %ebp.Таким образом, вы можете получить разумную трассировку стека, выполнив следующее:

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

xbt $ebp

Примечание: , если xbt сработает, он, вероятно, попадет в сорняки вокруг SIGSEGV сигнальный кадр (этот кадр также не использует указатель кадра).Это может привести к полному мусору или к пропущенному кадру или двум (которые будут в точности кадрами, в которых произошел SIGSEGV).

Так что вам действительно лучше получить правильные дескрипторы раскрутки в dietlibc.

...