【问题标题】:segmentation fault has occurred on a code which was not compiled using debugger flags未使用调试器标志编译的代码发生分段错误
【发布时间】:2015-12-23 17:49:34
【问题描述】:

我系统上的一个进程出现分段错误。 从核心文件中,我得到了以下信息。

#0  0x00007f8768c06cfb in TestDummy::work() () from libCont.so
#1  0x00007f8768bfb5ee in Test::work() () from libCont.so
#2  0x00007f8768c5fa7b in Test::worker_threads() () from libCont.so
#3  0x00007f873fffe830 in ?? ()
#4  0x0000000000000000 in ?? ()

请注意,我无法重新创建这个分段错误,我只有系统上的这个核心文件来识别出了什么问题。 注意:代码不是使用调试器标志编译的,即“g++ -g”,所以调试信息不​​可用。

我尝试了什么 我试图分解并读取完整的第 0 帧以识别确切的崩溃点,但它没有帮助。

谁能告诉我进一步调试的方法?

【问题讨论】:

    标签: c++ linux segmentation-fault gdb


    【解决方案1】:

    我试过什么我试图分解并读取完整的第 0 帧以识别确切的崩溃点,但它没有帮助

    您不需要确定确切的崩溃点:GDB已经告诉你它是什么:它是地址 0x7f8768c06cfb 处的指令。

    可能说的是“尽管查看了反汇编,但我仍然无法理解是哪个源代码行导致了问题”。我们可以为您提供帮助,但前提是您在问题中实际显示了源代码和反汇编代码。

    唯一的其他选择是:

    1. 找一位当地专家,您可以向他展示源代码和反汇编程序,并以与我们相同的方式为您提供帮助,或者
    2. 按照 Lightness Races in Orbit 告诉您的操作:使用完全相同相同的标志重建二进制文件,但还要添加 -g。假设你有一个密封的构建并且可以在足够接近的状态下重建你的原始二进制文件(nm new-binary 的输出应该与nm old-binary 的输出匹配),然后 GDB 会告诉你地址@的哪一行。 987654325@对应。

    注意:您实际上不必使用-g 重建整个 二进制文件。仅重建包含TestDummy::work() 的源并重新链接libCont.so 就足够了。

    【讨论】:

    • 感谢您的宝贵时间。您说得对,实际上,当我将它拆开时,它已经向我显示了带有标记(“=>”)的崩溃线。这样我就能够确定其中一个寄存器的值为空。仍然,我无法将该值映射到代码,因为 gdb 无法创建与该地址对应的符号。
    【解决方案2】:

    我认为有一种方法可以调试未使用调试器标志编译的内核。我想用下面的例子来解释一下。

    (gdb) disassemble 
    Dump of assembler code for function mystrcpy:  
     0x0804852a <+0>:   push   %ebp  
     0x0804852b <+1>:   mov    %esp,%ebp  
     0x0804852d <+3>:   sub    $0x10,%esp  
     0x08048530 <+6>:   mov    0x8(%ebp),%eax 
      0x08048533 <+9>:  mov    %eax,-0x4(%ebp)  
     0x08048536 <+12>:  jmp    0x8048540 <mystrcpy+22>
       0x08048538 <+14>:    addl   $0x1,0xc(%ebp)  
     0x0804853c <+18>:  addl   $0x1,0x8(%ebp)
       0x08048540 <+22>:    mov    0xc(%ebp),%eax 
      0x08048543 <+25>: movzbl (%eax),%edx 
      0x08048546 <+28>: mov    0x8(%ebp),%eax
    => 0x08048549 <+31>:    mov    %dl,(%eax)  
     0x0804854b <+33>:  mov    0x8(%ebp),%eax  
     0x0804854e <+36>:  movzbl (%eax),%eax
       0x08048551 <+39>:    test   %al,%al 
      0x08048553 <+41>: jne  
      0x8048538 <mystrcpy+14>  
     0x08048555 <+43>:  mov    -0x4(%ebp),%eax
       0x08048558 <+46>:    leave   
      0x08048559 <+47>: 
    ret    End of assembler dump.
    

    现在,实际显示“=>”符号的行是罪魁祸首。(=> 0x08048549 : mov %dl,(%eax))

    我们可以使用 gdb 命令来找出显示问题的行发生了什么。

      gdb) print $eax //print command
         $1 = 0
        (gdb) print $dl
         $2 = 118
        (gdb) print/c $dl
         $3 = 118 'v‘
        (gdb) info frame //info frame command
        Stack level 0, frame at 0xffbf8b90: eip = 0x8048549 in mystrcpy; saved eip =   0x80485cd called by frame at 0xffbf8bc0 Arglist at 0xffbf8b88, args:  Locals at 0xffbf8b88, Previous frame's sp is 0xffbf8b90 Saved registers:  ebp at 0xffbf8b88, eip at 0xffbf8b8c
        (gdb) x/x $ebp+4 //base pointer + 4 
        0xffbf8b8c: 0x080485cd
        (gdb) info symbol 0x080485cd  //info symbol command 
         connect + 115 in section .text of /home/vmahajan/a.out
         (gdb) x/x $ebp+4 
         0xffbf8b8c:    0x080485cd
        (gdb) x/x $ebp+8 
         0xffbf8b90:    0x00000000
        (gdb) x/x $ebp+12 
         0xffbf8b94:    0xffbf91f3
        (gdb) print/s (char *)0xffbf91f3
         $5 = 0xffbf91f3 "vishal“
    

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 1970-01-01
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      相关资源
      最近更新 更多