This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug other/13757] -fstack-check causes segfaults


------- Additional Comments From karsten_burger at gmx dot de  2004-08-04 11:35 -------
I would not like the "-fstack-check" to be removed from the compiler - it is needed to 
debug multi-threaded applications. Found the bug on Mandrake 9.1 with gcc 3.2.2, too. 
 
(In reply to comment #0) 
> The -fstack-check compiler option emits code which can make any program 
> segfault on entering its mainline. 
> The placement of the stack relative to page boundaries needs to be right 
> to demonstrate the problem. 
> This placement varies with environment, length of pathname used to invoke the 
> program, whether it is invoked directly or via GDB, 
> and quite possibly other factors also. 
> This is an old problem, I first saw it at gcc 2.95.3. 
> Shell/expect scripts in How-To-Repeat demonstrate the problem reliably. 
>  
> This is a dissasem of main() :- 
>  
> 0x8048354 <main>:       push   %ebp 
> 0x8048355 <main+1>:     mov    %esp,%ebp 
> 0x8048357 <main+3>:     sub    $0x18,%esp 
> 0x804835a <main+6>:     and    $0xfffffff0,%esp 
> 0x804835d <main+9>:     movl   $0x0,0xfffffffc(%ebp) 
> 0x8048364 <main+16>:    lea    0xffffded8(%esp,1),%eax 
> 0x804836b <main+23>:    mov    %eax,0xfffffff8(%ebp) 
> 0x804836e <main+26>:    mov    0xfffffffc(%ebp),%eax 
> 0x8048371 <main+29>:    add    $0x1128,%eax 
> 0x8048376 <main+34>:    mov    %esp,%edx 
> 0x8048378 <main+36>:    sub    %eax,%edx 
> 0x804837a <main+38>:    mov    %edx,0xfffffff4(%ebp) 
> 0x804837d <main+41>:    jmp    0x804838f <main+59> 
> 0x804837f <main+43>:    mov    0xfffffff8(%ebp),%eax 
> 0x8048382 <main+46>:    movl   $0x0,(%eax) 
> 0x8048388 <main+52>:    subl   $0x1000,0xfffffff8(%ebp) 
> 0x804838f <main+59>:    mov    0xfffffff4(%ebp),%edx 
> 0x8048392 <main+62>:    cmp    %edx,0xfffffff8(%ebp) 
> 0x8048395 <main+65>:    ja     0x804837f <main+43> 
> 0x8048397 <main+67>:    mov    0xfffffff4(%ebp),%eax 
> 0x804839a <main+70>:    movl   $0x0,(%eax) 
> 0x80483a0 <main+76>:    sub    0xfffffffc(%ebp),%esp 
> 0x80483a3 <main+79>:    lea    0xffffeed8(%esp,1),%eax 
> 0x80483aa <main+86>:    movl   $0x0,(%eax) 
> 0x80483b0 <main+92>:    movl   $0x8048424,(%esp,1) 
> 0x80483b7 <main+99>:    call   0x8048278 <printf> 
> 0x80483bc <main+104>:   mov    $0x0,%eax 
> 0x80483c1 <main+109>:   leave   
> 0x80483c2 <main+110>:   ret     
>  
> The segfault occurs at 0x804839a <main+70>:    movl   $0x0,(%eax) 
>  
> Environment: 
> System: Linux dimstar 2.4.24 #1 Sat Jan 10 17:03:52 EST 2004 i686 unknown 
> Architecture: i686 
>  
>          
> host: i686-pc-linux-gnu 
> build: i686-pc-linux-gnu 
> target: i686-pc-linux-gnu 
> configured with: /usr/src/gcc-3.3.2/configure --prefix=/usr/local/gcc3.2 
>  
> How-To-Repeat: 
> The preprocessed source:- 
>  
> ---------------------------- START hello.i ---------------------------- 
> extern int printf (__const char *__restrict __format, ...) ; 
> int main(int argc,char**argv) 
> { 
>         printf("\nHello World!\n\n"); 
>         return 0 ; 
> } 
> ---------------------------- END hello.i ---------------------------- 
>  
> This test script will verify that we get the crash. 
> It works by increasing the length of the pathname of hello 
> in 16 byte increnents until it crashes (copious output) :-  
>  
> ---------------------------- START sh.sh ---------------------------- 
> #!/bin/sh 
> gcc -g -Wall -fstack-check -o hello hello.i 
> i=aaaaaaaaaaaaaaa 
> j=`/bin/pwd` 
> while(true);do 
> $j/hello || break 
> j=$j/$i 
> mkdir -p $j 
> cp hello $j 
> done 
> echo "Failing path is $j" 
> ---------------------------- END sh.sh ---------------------------- 
>  
> This script discovers the required pathname to see the problem under gdb. 
> It saves this in the command file "cmd" for future use :- 
>  
> ---------------------------- START demo.sh ---------------------------- 
> #!/bin/sh 
> # expect treats all the shell lines as comment comtinuations \ 
> gcc -g -Wall -fstack-check -o hello hello.i; \ 
> i=aaaaaaaaaaaaaaa; \ 
> exec expect -f "$0" -- $i `/bin/pwd` 
>  
> # We need to find a path that shows the problem when run under gdb 
>  
> set i [lindex $argv 0] 
> set j [lindex $argv 1] 
>  
> puts "Finding a pathname that displays the problem." 
> puts "This may take a while..." 
> log_user 0 
>  
> spawn sh 
> expect "$ " 
> set k 0 
> set l 0 
> while {1} \ 
> { 
>   puts -nonewline "$l\r" 
>   flush stdout 
>   set l [incr l] 
>   exp_send "gdb $j/hello\r" 
>   expect "(gdb) " 
>   exp_send "run\r" 
>   expect \ 
>   { 
>     signal \ 
>     { 
>       set k 1 
>       expect "(gdb) " 
>       exp_send "q\r" 
>       expect "(y or n) " 
>       exp_send "y\r" 
>     } 
>     normally \ 
>     { 
>       expect "(gdb) " 
>       exp_send "q\r" 
>     } 
>   } 
>   expect "$ " 
>   if {$k} break 
>   set j $j/$i 
>   exec mkdir -p $j 
>   exec cp hello $j 
> } 
> puts "\nFailing path is $j" 
> exec echo "gdb $j/hello" > cmd 
> exec chmod a+x cmd 
> puts "gdb invocation command stored in ./cmd" 
> ---------------------------- END demo.sh ---------------------------- 
>  
> After running demo.sh, you can invoke gdb by running cmd directly. 
> Alternatively, you can run the following script to get directly to 
> the first machine instruction in main() :- 
>  
> ---------------------------- START run_gdb.sh ---------------------------- 
> #!/bin/sh 
> # expect treats all the shell lines as comment comtinuations \ 
> exec expect -f "$0" 
> spawn ./cmd 
> expect "(gdb) " 
> exp_send "b __libc_start_main\r" 
> expect "(gdb) " 
> exp_send "run\r" 
> expect "(gdb) " 
> exp_send "n 11\r" 
> expect "(gdb) " 
> exp_send "si 10\r" 
> expect "(gdb) " 
> puts "\n\nYou can now interact with gdb." 
> puts "If it won't exit for you (lost LWP or whatever), type \"////\" to kill it" 
> exp_send " \r" 
> interact //// exit 
> ---------------------------- END run_gdb.sh ---------------------------- 
>  
> At gcc3.2.2, you can use "si 17" to get to the actual failing instruction. 
> At that point if you note the contents of eax and use "x" to examine that 
> location, the program will continue without failing. 
>  
> Otherwise, 'movl   $0x0,(%eax)' will fail. 
> I do not understand why this should be. 
 
 

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13757


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]