This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

[RFA/commit] AIX: breakpoint in thread causes SIGTRAP


I am running on AIX 5.1, with a GCC compiler based on 3.2.3.

To reproduce the problem, do the following:

        % cd gdb/testsuite/gdb.threads
        % ../../gdb pthread_cond_wait
        (gdb) break noreturn
        (gdb) run

Sometimes I get the following (expected) output:

        [Switching to Thread 258]
        
        Breakpoint 1, noreturn () at gdb.threads/pthread_cond_wait.c:41
        41        pthread_mutex_init (&mut, NULL);

But sometimes, I get the following unexpected output (roughly 60% of
the time, I counted 12 times out of 20 tries :-):

        Breakpoint 1 at 0x1000045c: file gdb.threads/pthread_cond_wait.c,
        line 41.
        
        Program received signal SIGTRAP, Trace/breakpoint trap.
        [Switching to Thread 1]
        0xd0054000 in _vp_start () from /usr/lib/libpthreads.a(shr_xpg5.o)

Here is short description of what's causing GDB to believe this
SIGTRAP is a "random signal".

Once the startup is completed, the program runs until it hits our
breakpoint. After stopping, aix-threads resyncs our thread list,
and then looks for the thread which caused the stop by checking
which one received a SIGTRAP signal. Unfortunately, it sometimes doesn't
find it, and that causes GDB to sort of end up in the wrong thread,
which then causes it to miss the fact that one other thread hit a
breakpoint.

The reason for this is a misunderstanding in the usage of getthrds().
In "Base Operating System and Extensions Technical Reference, Volume 1",
the documentation says that the 4th parameter named "IndexPointer" 
"Specifies the address of a kernel thread identifier which indicates
the required kernel thread table entry (this does not have to correspond
to an existing kernel thread). A kernel thread identifier of zero selects
the first entry in the table. The kernel thread identifier is updated
to indicate the next entry to be retrieved.". This is not a pointer to
the kernel TID as our current usage in aix-thread.c seems to indicate.
It's just an address.

So what I did was follow the recommended approach, which is to loop
over all kernel threads with successive calls to getthrds() until
I found the kernel thread that received a SIGTRAP. I then iterate
over all GDB threads until I find the one that corresponds to it.

2004-07-29  Joel Brobecker  <brobecker@gnat.com>

        * aix-thread.c (get_signaled_thread): New function.
        (iter_trap): Delete, no longer used.
        (iter_tid): New function.
        (pd_update): Find the thread that received the SIGTRAP signal
        by first locating the kernel thread, and then finding its
        associated thread.

Tested on AIX 5.1, no regression. Fixes the problem described above,
20 good runs in a row :-). I will submit a testcase for this hopefully
today.

I'll commit this change on Monday. Peter, Kevin, let me know if you'd
like me to delay this patch, if you want to review it later.

-- 
Joel

Attachment: aix-thread.c.diff
Description: Text document


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