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

问题描述 投票:3回答:2

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

catch syscall socketcall

...哪个工作正常。但是,当实际上遇到一个断点时,回溯总是看起来相同:

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

这就是她写的全部!为什么GDB无法遍历堆栈并显示完整的堆栈跟踪信息,直到main

debugging gdb system-calls
2个回答
5
投票

为什么GCC不能遍历堆栈并显示完整的堆栈跟踪信息一直到main?

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


0
投票

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

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
© www.soinside.com 2019 - 2024. All rights reserved.