Bug 21806 - Incorrect stack allocation of complex objects
Summary: Incorrect stack allocation of complex objects
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.4
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-05-29 12:50 UTC by Piotr Kolaczkowski
Modified: 2005-08-26 03:52 UTC (History)
2 users (show)

See Also:
Host:
Target: i386-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Piotr Kolaczkowski 2005-05-29 12:50:55 UTC
The bug leads to corruption of program's data. Two objects on the stack overlap 
so that the constructor of the second one erases some data of the first one.  
I've checked the whole program with valgrind and it didn't report anything  
incorrect that I might have done with memory allocation, pointers etc. Bug  
exists independently from optimization flags. 
 
Incorrect program fragment:  
--------------------------------------------------------- 
 
int main(int argc, char* argv[])  
{       
    THttpServer HttpServer;                
    THttpSessionBroker SessionBroker;    // error occurs at this line 
 
    SessionBroker.SetServletConstructor(&TMainServlet::Create);         
    HttpServer.RegisterServlet(&SessionBroker, "/");        
    HttpServer.SetLocalPort(8888); 
    HttpServer.Run();     
} 
 
GDB session that proves objects are not placed on the  
stack as they should be: 
---------------------------------------------------------- 
 
GNU gdb 5.3 
Copyright 2002 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB.  Type "show warranty" for details. 
This GDB was configured as "i386-slackware-linux"... 
(gdb) break main.cpp:25 
Breakpoint 1 at 0x80492a4: file main.cpp, line 25. 
(gdb) run 
Starting program: /home/pkolaczk/projects/dns/dns 
[New Thread 16384 (LWP 5218)] 
[New Thread 32769 (LWP 5219)] 
[New Thread 16386 (LWP 5220)] 
[New Thread 32771 (LWP 5221)] 
[New Thread 49154 (LWP 5222)] 
[Switching to Thread 16384 (LWP 5218)] 
 
Breakpoint 1, main (argc=1, argv=0xbffff7f4) at main.cpp:26 
26          THttpServer HttpServer; 
(gdb) next 
[New Thread 65539 (LWP 5223)] 
[New Thread 81924 (LWP 5224)] 
[New Thread 98309 (LWP 5225)] 
[New Thread 114694 (LWP 5226)] 
[New Thread 131079 (LWP 5227)] 
27          THttpSessionBroker SessionBroker; 
(gdb) print &HttpServer 
$1 = (THttpServer *) 0xbffff760 
(gdb) print sizeof(HttpServer) 
$2 = 48 
(gdb) print &SessionBroker 
$3 = (THttpSessionBroker *) 0xbffff6a0 
(gdb) print sizeof(SessionBroker) 
$4 = 272 
(gdb) print &SessionBroker.SessionTimer 
$5 = (class TTimer *) 0xbffff6e0 
(gdb) print &SessionBroker.SessionTimer.Stopper 
$6 = (TMutex *) 0xbffff758 
(gdb) print &SessionBroker.SessionTimer.TaskListProtection 
$7 = (TMutex *) 0xbffff774                   // ITS BEYOND 0xbffff760 !!! 
(gdb) x/8xa 0xbffff760 
0xbffff760:     0x804e2d8       0x804e2d0       0x804e670       0x804e668 
0xbffff770:     0x804e3d0       0x804e3c8       0x804e200       0x804e1f8 
(gdb) next                        // create the second object 
[New Thread 147464 (LWP 5228)] 
29          HttpServer.RegisterServlet(&SessionBroker, "/"); 
(gdb) x/8xa 0xbffff760 
0xbffff760:     0x0     0x0     0xbebff990      0x0 
0xbffff770:     0x804e3d0       0x804e3c8       0x0     0x0 
(gdb)                                                                                   
 
Seems the overlapping area is at least 28 bytes large. 
By more extensive debugging I've found out that the stack corruption occurs in  
the constructor of SessionBroker.SessionTimer.Stopper object which only sets  
some of its fields and doesn't do any pointer arithmetic or anything that  
could write to memory it shouldn't. Everytime I run the program, everything  
goes the same way. The bug is not random as opposed to ordinary memory  
bugs. 
 
I've also made some experiments - putting an array between the two objects  
helps: 
 
int main(int argc, char* argv[])  
{       
    THttpServer HttpServer;                
    int a[8]; 
    THttpSessionBroker SessionBroker; 
 
    //SessionBroker.SetServletConstructor(&TMainServlet::Create);         
    HttpServer.RegisterServlet(&SessionBroker, "/");        
    HttpServer.SetLocalPort(8888); 
    HttpServer.Run();     
} 
 
Also if compiled with gcc 2.95.3, everything worked fine. 
 
Having this evidence (especially the gdb output), can it be the fault of my  
program or is it rather a compiler bug? Have I missed something? 
I can send you a complete source code if needed. 
 
Additional information: 
 
system type: Linux 2.6.11.7 
processor: i686 (Pentium Celeron 2.4 GHz / 128k L2 cache) 
gcc version: 3.4.4 built from sources in a default way: "./configure" without  
any additional options
Comment 1 Andrew Pinski 2005-05-29 14:06:54 UTC
Could you attach the preprocessed source?
Comment 2 Andrew Pinski 2005-06-19 13:58:44 UTC
We need the preprocessed source to reproduce this.
Comment 3 Andrew Pinski 2005-08-26 03:52:43 UTC
No feed back in 3 months (T-4 days).