public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/13757] New: -fstack-check can crash Hello World
@ 2004-01-20  4:30 gcc-bugzilla at gcc dot gnu dot org
  2004-01-20  4:38 ` [Bug c/13757] " pinskia at gcc dot gnu dot org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: gcc-bugzilla at gcc dot gnu dot org @ 2004-01-20  4:30 UTC (permalink / raw)
  To: gcc-bugs

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.
------- Additional Comments From duncan_roe at acslink dot net dot au  2004-01-20 04:29 -------
Fix:
Workaround: don't use -fstack-check

-- 
           Summary: -fstack-check can crash Hello World
           Product: gcc
           Version: 3.3.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: duncan_roe at acslink dot net dot au
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/13757] -fstack-check can crash Hello World
  2004-01-20  4:30 [Bug c/13757] New: -fstack-check can crash Hello World gcc-bugzilla at gcc dot gnu dot org
@ 2004-01-20  4:38 ` pinskia at gcc dot gnu dot org
  2004-01-21  6:22 ` [Bug c/13757] -fstack-check causes segfaults dhazeghi at yahoo dot com
  2004-08-04 11:36 ` [Bug other/13757] " karsten_burger at gmx dot de
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-01-20  4:38 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-01-20 04:38 -------
I really think -fstack-check should be removed from the compiler, its use is no longer needed.

-- 


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/13757] -fstack-check causes segfaults
  2004-01-20  4:30 [Bug c/13757] New: -fstack-check can crash Hello World gcc-bugzilla at gcc dot gnu dot org
  2004-01-20  4:38 ` [Bug c/13757] " pinskia at gcc dot gnu dot org
@ 2004-01-21  6:22 ` dhazeghi at yahoo dot com
  2004-08-04 11:36 ` [Bug other/13757] " karsten_burger at gmx dot de
  2 siblings, 0 replies; 4+ messages in thread
From: dhazeghi at yahoo dot com @ 2004-01-21  6:22 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From dhazeghi at yahoo dot com  2004-01-21 06:22 -------
Confirmed with mainline. You have to run the testcase a few times, but on one, it'll inevitably 
crash. Only options needed to reproduce are "-fstack-check"

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|                            |1
           Keywords|                            |wrong-code
   Last reconfirmed|0000-00-00 00:00:00         |2004-01-21 06:22:17
               date|                            |
            Summary|-fstack-check can crash     |-fstack-check causes
                   |Hello World                 |segfaults


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug other/13757] -fstack-check causes segfaults
  2004-01-20  4:30 [Bug c/13757] New: -fstack-check can crash Hello World gcc-bugzilla at gcc dot gnu dot org
  2004-01-20  4:38 ` [Bug c/13757] " pinskia at gcc dot gnu dot org
  2004-01-21  6:22 ` [Bug c/13757] -fstack-check causes segfaults dhazeghi at yahoo dot com
@ 2004-08-04 11:36 ` karsten_burger at gmx dot de
  2 siblings, 0 replies; 4+ messages in thread
From: karsten_burger at gmx dot de @ 2004-08-04 11:36 UTC (permalink / raw)
  To: gcc-bugs


------- 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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-08-04 11:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-20  4:30 [Bug c/13757] New: -fstack-check can crash Hello World gcc-bugzilla at gcc dot gnu dot org
2004-01-20  4:38 ` [Bug c/13757] " pinskia at gcc dot gnu dot org
2004-01-21  6:22 ` [Bug c/13757] -fstack-check causes segfaults dhazeghi at yahoo dot com
2004-08-04 11:36 ` [Bug other/13757] " karsten_burger at gmx dot de

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).