为什么gdb backtrace在捕获系统调用时只显示一帧?

时间:2015-04-21 06:52:53

标签: debugging gdb system-calls

我正在尝试查找正在运行的程序源中使用某些系统调用的所有位置。我设置了断点,如:

catch syscall socketcall

......哪个工作正常。但是,当其中一个断点实际被击中时,回溯看起来总是一样:

(gdb) bt
#0  __cp_end () at src/thread/i386/syscall_cp.s:25

这就是她写的全部内容!为什么GCC不能走堆栈并显示完整的堆栈跟踪一直到main

2 个答案:

答案 0 :(得分:3)

  

为什么GCC不能走堆栈并显示一直到主要的完整堆栈跟踪?

最有可能的原因是syscall_cp.s中的手写程序集缺少展开描述符,并且没有使用帧指针。 GDB 需要一个或另一个。另请参阅this answer

答案 1 :(得分:3)

专门针对MIPS,我必须将以下补丁应用于musl以获得有意义的堆栈跟踪。请记住,我不太清楚自己在做什么,但这对我有用。我希望有时间向上游提交此文件,但是它非常hackack,不完整,而且我不知道自己在做什么。不过,这里是:

diff --git a/src/internal/mips/syscall.s b/src/internal/mips/syscall.s
index 5d0def52..f9bc599d 100644
--- a/src/internal/mips/syscall.s
+++ b/src/internal/mips/syscall.s
@@ -4,6 +4,7 @@
 .hidden __syscall
 .type   __syscall,@function
 __syscall:
+    .cfi_startproc
    move    $2, $4
    move    $4, $5
    move    $5, $6
@@ -13,6 +14,7 @@ __syscall:
    lw      $9, 24($sp)
    lw      $10,28($sp)
    subu    $sp, $sp, 32
+   .cfi_adjust_cfa_offset 32
    sw      $8, 16($sp)
    sw      $9, 20($sp)
    sw      $10,24($sp)
@@ -21,6 +23,8 @@ __syscall:
    syscall
    beq     $7, $0, 1f
    addu    $sp, $sp, 32
+    .cfi_adjust_cfa_offset -32
    subu    $2, $0, $2
 1: jr      $ra
    nop
+   .cfi_endproc
diff --git a/src/ldso/mips/dlsym.s b/src/ldso/mips/dlsym.s
index 1573e519..f1036621 100644
--- a/src/ldso/mips/dlsym.s
+++ b/src/ldso/mips/dlsym.s
@@ -3,15 +3,21 @@
 .hidden __dlsym
 .type dlsym,@function
 dlsym:
+    .cfi_startproc
    lui $gp, %hi(_gp_disp)
    addiu $gp, %lo(_gp_disp)
    addu $gp, $gp, $25
    move $6, $ra
    lw $25, %call16(__dlsym)($gp)
    addiu $sp, $sp, -16
+   .cfi_adjust_cfa_offset 16
    sw $ra, 12($sp)
+    .cfi_rel_offset $ra, 12
    jalr $25
    nop
    lw $ra, 12($sp)
+    .cfi_restore $ra
    jr $ra
    addiu $sp, $sp, 16
+   .cfi_adjust_cfa_offset -16
+   .cfi_endproc
diff --git a/src/thread/mips/syscall_cp.s b/src/thread/mips/syscall_cp.s
index d2846264..ab173496 100644
--- a/src/thread/mips/syscall_cp.s
+++ b/src/thread/mips/syscall_cp.s
@@ -14,9 +14,12 @@
 .hidden __syscall_cp_asm
 .type   __syscall_cp_asm,@function
 __syscall_cp_asm:
+    .cfi_startproc
    subu    $sp, $sp, 32
+   .cfi_adjust_cfa_offset 32
 __cp_begin:
    lw      $4, 0($4)
+   .cfi_remember_state
    bne     $4, $0, __cp_cancel
    move    $2, $5
    move    $4, $6
@@ -35,14 +38,18 @@ __cp_begin:
 __cp_end:
    beq     $7, $0, 1f
    addu    $sp, $sp, 32
+   .cfi_adjust_cfa_offset -32
    subu    $2, $0, $2
 1: jr      $ra
    nop

 __cp_cancel:
+    .cfi_restore_state
    move    $2, $ra
+   .cfi_register $ra, $2
    bal     1f
    addu    $sp, $sp, 32
+   .cfi_adjust_cfa_offset -32
    .gpword .
    .gpword __cancel
 1: lw      $3, ($ra)
@@ -51,3 +58,5 @@ __cp_cancel:
    addu    $25, $25, $3
    jr      $25
    move    $ra, $2
+   .cfi_restore $ra
+   .cfi_endproc
-- 
2.24.0