SIGSEGV: exceptions with thread specific data
Andrey Slepuhin
pooh@msu.ru
Fri Mar 12 04:37:00 GMT 1999
On 10-Mar-99 Zack Weinberg wrote:
> On 10 Mar 1999 18:30:10 -0000, Wolfram Gloger wrote:
>>> I would like to report a problem (possible bug) in exception
>>> code, but it could also be a problem in glibc-2.0.7 or linuxthreads.
>>>
>>> Please let me know if this problem exists on glibc-2.1.X or egcs-1.1.X
>>> or if it is a bug of egcs or glibc or linuxthreads
>>
>>Please try at least egcs-1.1.1 -- versions before that are known to be
>>unsafe with regard to threaded exception handling.
>
> The bug appears with egcs-1.1.1 and the development egcs as well, and
> with glibc 2.1.x (x=0 and x=1).
>
> If I replace pthreads with a fake library that doesn't actually use
> threads, then the egcs-1.1.1 compiled version segfaults in
> __cp_push_exception, but the development version works correctly. The
> segfault with 1.1.1 and the fake library is a different bug: with the
> real library, the thread executes successfully and the crash is in
> pthread_join - I think (I'm having trouble tracing it).
>
> I am guessing that there is a bug in the EH library routines which
> causes them to corrupt the malloc arena, and this code tickles it.
> (Yes, glibc's malloc() is threadsafe.)
>
> Incidentally, on sparc-sun-solaris2.6 this program executes correctly
> when compiled by egcs 1.1, using either the system threads library or
> my fake library. This may mean the bug is in Linux pthreads, or that
> Solaris malloc() isn't as sensitive to corruption, or that the problem
> is machine-dependent in egcs.
>
> The fake library source is appended. The typedefs are correct for
> glibc and Solaris pthreads; you may have to adjust this for other
> systems.
>
> [There seems to be a lot of unnecessary code in the asm dump for the
> test function - e.g. we ought to be able to figure out at compile time
> that the try region will only ever throw an int, and omit the
> unhandled exception code and the type verification. Actually, we
> ought to be able to delete the entire thing except for the printf.]
>
> zw
Hi,
I have the same bug in the following configuration:
linux-2.2.1
egcs-1.1.1
binutils-2.9.1.0.19a
glibc-2.0.7-29 (from RH-5.2).
I modified original t.cc file in the following way:
----------------------------------------------------
#include <pthread.h>
#include <stdio.h>
#include <malloc.h>
#include <mcheck.h>
#define WR(msg) write(1,msg,sizeof(msg))
void (*old_free_hook)(void*) = __free_hook;
void* (*old_malloc_hook)(size_t) = __malloc_hook;
void my_free_hook(void *ptr)
{
__free_hook = old_free_hook;
switch (mprobe(ptr)) {
case MCHECK_DISABLED:
printf("MCHECK_DISABLED\n"); break;
case MCHECK_OK:
printf("MCHECK_OK at %p\n",ptr); break;
case MCHECK_HEAD:
printf("MCHECK_HEAD at %p\n",ptr); break;
case MCHECK_TAIL:
printf("MCHECK_TAIL at %p\n",ptr); break;
case MCHECK_FREE:
printf("MCHECK_FREE at %p\n",ptr); break;
}
free(ptr);
__free_hook=my_free_hook;
}
void* my_malloc_hook(size_t size)
{
__malloc_hook = old_malloc_hook;
void* ptr=malloc(size);
switch (mprobe(ptr)) {
case MCHECK_DISABLED:
printf("MCHECK_DISABLED\n"); break;
case MCHECK_OK:
printf("MCHECK_OK at %p\n",ptr); break;
case MCHECK_HEAD:
printf("MCHECK_HEAD at %p\n",ptr); break;
case MCHECK_TAIL:
printf("MCHECK_TAIL at %p\n",ptr); break;
case MCHECK_FREE:
printf("MCHECK_FREE at %p\n",ptr); break;
}
__malloc_hook=my_malloc_hook;
return ptr;
}
pthread_key_t key;
void *main_thr(void *)
{
int i;
WR("0006\n");
// here linuxthreads allocate through calloc thread specific data
pthread_setspecific(key, "asd");// try move after catch
WR("0007\n");
try {
throw 1; // try disable
}
catch (int i) {
WR("0008\n");
printf("cought\n");
}
WR("0009\n");
pthread_setspecific(key, NULL);
WR("0010\n");
}
void main()
{
__free_hook=my_free_hook;
__malloc_hook=my_malloc_hook;
pthread_t t_id;
WR("0001\n");
pthread_key_create(&key, NULL);
WR("0002\n");
pthread_create(&t_id, NULL, main_thr, NULL);
WR("0003\n");
sleep(5); // Be sure that threads are not interfered
pthread_join(t_id, NULL);
WR("0004\n");
pthread_key_delete(key); // try disable
WR("0005\n");
exit(0);
}
----------------------------------------------------
Then:
g++ -D_REENTRANT -c -o t.o t.cc
g++ -o t t.o -lpthread -lmcheck
And after debugging I have:
pooh@glade:~/test$ gdb ./t
GNU gdb 4.17.0.8 with Linux support
Copyright 1998 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 "i586-pc-linux-gnu"...
(gdb) run
Starting program: /local/users/pooh/test/./t
0001
0002
MCHECK_OK at 0x804a2a8
[New Thread 27851]
[New Thread 27850]
[New Thread 27852]
0006
0003
memory clobbered before allocated block
Program received signal SIGABRT, Aborted.
[Switching to Thread 27852]
Program received signal SIGABRT, Aborted.
0x40091811 in __kill ()
(gdb) bt
#0 0x40091811 in __kill ()
#1 0x4009163f in raise (sig=6) at ../sysdeps/posix/raise.c:27
#2 0x4009284f in abort () at ../sysdeps/generic/abort.c:83
#3 0x400b0dd3 in __libc_fatal (message=0x40104f3c "")
at ../sysdeps/posix/libc_fatal.c:56
#4 0x400b6fc1 in mabort (status=MCHECK_HEAD) at mcheck.c:198
#5 0x400b6bed in checkhdr (hdr=0x804c288) at mcheck.c:90
#6 0x400b70bc in mprobe (ptr=0x804c290) at mcheck.c:232
#7 0x8048b90 in my_malloc_hook ()
#8 0x400b5510 in __libc_calloc (n=32, elem_size=4) at malloc.c:3476
#9 0x400141d1 in __pthread_setspecific (key=0, pointer=0x8048f66)
at specific.c:102
#10 0x8048c48 in main_thr ()
#11 0x40012357 in pthread_start_thread (arg=0xbf9ffea4) at manager.c:192
(gdb)
As you can see, memory allocation error was shown during during first
pthread_setspecific() call *before* "try" block.
Moreover, memory error remains after commenting entire "try" part of a program.
I didn't look into glibc sources yet, but I can guess that this is glibc's
problem rather than egcs'.
Regards,
Andrey.
More information about the Gcc-bugs
mailing list