This is the mail archive of the
gdb-prs@sources.redhat.com
mailing list for the GDB project.
gdb/1356: Threads not handled properly when returning from breakpoint
- From: rtrask at broadcom dot com
- To: gdb-gnats at sources dot redhat dot com
- Date: 28 Aug 2003 18:22:28 -0000
- Subject: gdb/1356: Threads not handled properly when returning from breakpoint
- Reply-to: rtrask at broadcom dot com
>Number: 1356
>Category: gdb
>Synopsis: Threads not handled properly when returning from breakpoint
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Aug 28 18:28:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: rtrask@broadcom.com
>Release: 5.3
>Organization:
>Environment:
Linux, Redhat 7.1
>Description:
When running a multi-threaded program gdb erroneously awakens (all) sleeping threads when returning from a breakpoint in another thread.
I have a small file "alarm_thread.c" (from David Butendorf's Programming with Posix Threads) that demonstrates this.
This program works properly outside of gdb.
>How-To-Repeat:
Compile alarm_thread.c as follows:
gcc -D_REENTRANT -lpthread -g alarm_thread.c -o alarm_thread
gdb alarm_thread
b 53
run
{enter alarm duration and "name" at the Alarm> prompt, bp will hit just after entry and before creating thread to handle alarm timer. Make sure to enter large enough times e.g. 300 seconds so that alarm expiration will not occur)
Enter multiple alarms, note that alarms previously entered will report even though their timers have not expired.
You can check status using info threads et al and discover threads that were created and sleeping on [entered timeouts] have disappeared after returning from the breakpoint.
This occurs no matter how I return from the breakpoint, either by hitting "c" or "thread apply <thread num> c".
I have tried this with the most current version of gdb and the weekly snapshot, behavior is the same.
If someone has a fix or proposed patches I am willing to try them out and report results.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="alarm_thread.c"
Content-Disposition: inline; filename="alarm_thread.c"
/*
* alarm_fork.c
*
* This version of alarm.c uses pthread_create to create a
* separate thread to wait for each alarm to expire.
*/
#include <pthread.h>
#include "errors.h"
typedef struct alarm_tag {
int seconds;
char message[64];
} alarm_t;
void *alarm_thread (void *arg)
{
alarm_t *alarm = (alarm_t*)arg;
int status;
status = pthread_detach (pthread_self ());
if (status != 0)
err_abort (status, "Detach thread");
sleep (alarm->seconds);
printf ("(%d) %s\n", alarm->seconds, alarm->message);
free (alarm);
return NULL;
}
int main (int argc, char *argv[])
{
int status;
char line[128];
alarm_t *alarm;
pthread_t thread;
while (1) {
printf ("Alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
if (strlen (line) <= 1) continue;
alarm = (alarm_t*)malloc (sizeof (alarm_t));
if (alarm == NULL)
errno_abort ("Allocate alarm");
/*
* Parse input line into seconds (%d) and a message
* (%64[^\n]), consisting of up to 64 characters
* separated from the seconds by whitespace.
*/
if (sscanf (line, "%d %64[^\n]",
&alarm->seconds, alarm->message) < 2) {
fprintf (stderr, "Bad command\n");
free (alarm);
} else {
status = pthread_create (
&thread, NULL, alarm_thread, alarm);
if (status != 0)
err_abort (status, "Create alarm thread");
}
}
}