[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

OpenBSD g++ (propolice) compiler bug?

It seems that the default C++ compiler with OpenBSD-current
has some issues with the generated binary when compiling code
that uses C++ exceptions.

System 1:
OS:		OpenBSD-current (as of Feb 19, 2005)
Arch:		amd64
C++ compiler:	g++ (GCC) 3.3.5 (propolice)

System 2:
OS:		OpenBSD-current (as of January 19, 2005)
Arch:		i386
C++ compiler:	g++ (GCC) 3.3.5 (propolice)

At the end of this email I include an example that triggers the
problem on both systems described above. Note that this is the
simplest example I could come up with after trimming-down the
original program of few thousand lines. Also, note that practically
every statement has to be as-is, because even, say, some simple
variable reordering may prevent from triggering the bug.

When I compile and run the program (which should be perfectly legal
C++ code), it coredumps on exiting my_test_func():

_xorp_(_at_)_gauss[712] g++ my_test.cc 
_xorp_(_at_)_gauss[713] ./a.out 
main() starting...
my_test_func() starting...
P1: 12
P2: 20
my_test_func() exiting...
Abort (core dumped)
Exit 134

The gdb trace is:

(gdb) where
#0  0x00000000462991da in kill () from /usr/lib/libc.so.34.2
#1  0x000000004629eba0 in __stack_smash_handler () from /usr/lib/libc.so.34.2
#2  0x0000000000400e5c in my_test_func() ()
#3  0x0000000000400e76 in main ()

>From the above trace, my best guess is that somehow the C++ compiler
generates bogus code that tries to corrupt the stack, and this
triggers the call to __stack_smash_handler().
Indeed, if I use the -fno-stack-protector option to g++, then
the code runs fine.

Furthermore, if I use "eg++ (GCC) 3.4.3" on i386 from ports, the
program runs fine, but this is probably because it doesn't have



 * If I use -fno-stack-protector then no crash.

#include <exception>
#include <stdlib.h>
#include <stdio.h>

class MyException {
    MyException() {}

class MyClass {
    MyClass() : _af(55) {}
    char _addr[16];
    int _af;

    printf("my_test_func() starting...\n");

    try {
    } catch (const MyException& e1) {

	char foo1[12];
	printf("P1: %u\n", static_cast<unsigned int>(sizeof foo1));

    try {
	MyClass foo2;
	printf("P2: %u\n", static_cast<unsigned int>(sizeof foo2));
    } catch (...) {

    printf("my_test_func() exiting...\n");

    printf("main() starting...\n");
    printf("main() exiting...\n");