【问题标题】:segmentation fault x86 <_dl_debug_state>分段错误 x86 <_dl_debug_state>
【发布时间】:2012-05-26 20:15:08
【问题描述】:

我有一些由我自己的编译器制作的 asm 程序,当我想运行它们时,它们最后出现了分段错误。所有指令都按我想要的方式执行,但执行由段错误完成。

当我尝试使用 gdb 来查看段错误时,它似乎总是出现在以下行:0x11ee90 <_dl_debug_state> push %ebp>

我什至不知道这条线是什么,首先如何防止它导致段错误。

这里是这种程序的一个例子:

    file    "test_appel.c"
    .text                
.globl f  
    .type f, @function  
f:                        
    pushl   %ebp                     
    movl    %esp,   %ebp               
    subl    $16,    %esp
    movl    8(%ebp), %eax 
    pushl   %eax                        
    movl    12(%ebp), %eax 
    popl    %ecx          
    imull   %ecx,   %eax  
    movl    %eax,   16(%ebp) 
    movl    16(%ebp), %eax 
    leave
    ret         
    .section    .rodata
.LC0:
    .string "appel à fonction pour la multiplication\n"
.LC1:
    .string "resultat 2 * 3 = %d\n"
    .text                
.globl main  
    .type main, @function  
main:                        
    pushl   %ebp                     
    movl    %esp,   %ebp               
    andl    $-16,   %esp  
    subl    $32,    %esp
    movl    $2, %eax 
    movl    %eax,   8(%ebp) 
    movl    $3, %eax 
    movl    %eax,   12(%ebp) 
    movl    12(%ebp), %eax 
    movl    %eax    ,4(%esp) 
    movl    8(%ebp), %eax 
    movl    %eax    ,0(%esp) 
    call    f
    movl    %eax,   4(%ebp) 
    movl    4(%esp),    %eax    
    movl    (%esp), %ecx     
    pushl   %eax             
    pushl   %ecx             
    movl     $.LC0, %eax 
    movl    %eax,   (%esp)  
    call    printf         
    popl    %ecx             
    popl    %eax             
    movl    %eax,   4(%esp)   
    movl    %ecx,   (%esp)    
    movl    4(%esp),%eax      
    movl    (%esp), %ecx     
    pushl   %eax             
    pushl   %ecx             
    movl    4(%ebp), %eax 
    movl    %eax,   %edx
    movl    %edx,   4(%esp)                    
    movl    $.LC1,  (%esp)  
    call    printf                            
    popl    %ecx             
    popl    %eax             
    movl    %eax,   4(%esp)   
    movl    %ecx,   (%esp)    
    leave
    ret  

【问题讨论】:

    标签: assembly gdb segmentation-fault glibc


    【解决方案1】:

    segfault,似乎总是出现在以下行:0x11ee90 &lt;_dl_debug_state&gt; push %ebp&gt;

    这只是意味着你已经损坏或耗尽了堆栈。

    实际上,您的编译器确实会发出会破坏整个堆栈的代码。特别是这些说明:

    movl    %eax,   8(%ebp)
    ...
    movl    %eax,   12(%ebp) 
    

    在你的调用者(它是libc的一部分)中损坏了局部变量,所以在main返回之后看到崩溃并不奇怪。

    您可能打算发出:movl %eax, -8(%ebp)movl %eax, -12(%ebp)

    【讨论】:

      【解决方案2】:

      when i try to use gdb in order to look at the segfault, it appears that it always occurs at the line : 0x11ee90 &lt;_dl_debug_state&gt; push %ebp&gt;

      在函数调用期间发生分段错误:%ebp 被压入堆栈。这看起来像是较早发生的堆栈损坏的后果。

      您没有从 GDB 共享完整的堆栈跟踪,也没有共享地址空间信息。

      在 gdb 中,当它出现段错误时,执行 disassemble 以获取更多信息,并执行 bt 以获取所有被调用的函数以达到此目的。

      【讨论】:

        【解决方案3】:

        问题是您正在破坏返回指令。如您所知,ebp + 4 始终包含执行被调用函数后控件跳转的返回指令地址。在你的情况下,你有这样的声明:

               movl    %eax,   4(%ebp)
        

        您正在将“f()”的返回值写入 ebp+4,这会破坏返回指令地址。你删除这个语句你不会得到分段错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-02
          • 2016-02-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-31
          • 2019-09-30
          相关资源
          最近更新 更多