This is the mail archive of the 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]

single-stepping and internal breakpoints on a multi-threaded program

Hello members, 

My colleague has found a problem about handling single-stepping on a
multi-threaded target running on Linux box.  

The attached program makes two sub threads, and we do single-stepping
on one of them.  
When the target get stopped by a internal breakpoint hit (ex. thread
creation, thread death, shared library loading) during singe-stepping,
GDB unconditionally resume all the thread and it result in running
over the range of single-stepping.  

The session log below shows one of the phenomena reproduced on X86
FC6; the problem occured when the second thread was created.  
I can see them 10-20% of the time on our Cell hardware running FC5
(note that the program is compiled just for PPC64) and X86 FC5/FC6.  

GNU gdb
Copyright (C) 2007 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 "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/".
(gdb) b 14
Breakpoint 1 at 0x80484fa: file mt.c, line 14.
(gdb) l 14
9       {
10        int i;
11        int cnt = *((int *) arg);
12        pid_t pid = getpid();
14        for (i=0; i<cnt; i++)
15          printf ("[%d]counter: %d\n", pid, i);
17        return NULL;
18      }
(gdb) r
Starting program: /project/07/user/suzuki/test/mt/mt
[Thread debugging using libthread_db enabled]
[New Thread -1208011072 (LWP 28472)]
[New Thread -1208013936 (LWP 28475)]
[Switching to Thread -1208013936 (LWP 28475)]

Breakpoint 1, counter (arg=0xbfd491b0) at mt.c:14
14        for (i=0; i<cnt; i++)
(gdb) s
[New Thread -1218503792 (LWP 28476)]
[Thread -1218503792 (LWP 28476) exited]
[28472]counter: 0
[28472]counter: 1
[28472]counter: 2
[28472]counter: 3
[28472]counter: 4
[28472]counter: 5
[28472]counter: 6
[28472]counter: 7
[28472]counter: 8
[28472]counter: 9
[Thread -1208013936 (LWP 28475) exited]
Thread Event Breakpoint: gdb should not stop!

I saw that the context of single-stepping thread is preserved by
context_switch called in handle_inferior_event, but GDB doesn't go
back to that context till the thread is trapped in another reason
(in the above case, the death of the thread).  

I think it should either stop immediately and prompt the user that the
single-stepping has been cancelled, or goes back to the preserved
context somehow and continue single-stepping.  
How do you think of it? 

Thanks in advance, 
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

void *
counter(void *arg)
  int i;
  int cnt = *((int *) arg);
  pid_t pid = getpid();

  for (i=0; i<cnt; i++)
    printf ("[%d]counter: %d\n", pid, i);

  return NULL;

void *
no_counter (void *arg)
  pid_t pid = getpid();

  printf ("[%d]no_counter\n", pid);

  return NULL;

main (void)
  pid_t p_pid;
  pthread_t thread_id1, thread_id2;
  int status;
  int count = 10;

  p_pid = getpid ();
  printf ("[%d]start\n", p_pid);

  status = pthread_create (&thread_id1, NULL, counter, (void *)&count);
  if (status != 0)
      fprintf (stderr, "pthread_create : %s", strerror(status));
      return (1);

  status = pthread_create (&thread_id2, NULL, no_counter, (void *)NULL);
  if (status != 0)
      fprintf (stderr, "pthread_create : %s", strerror(status));
      pthread_join (thread_id1, NULL);
      return (1);

  pthread_join (thread_id2, NULL);
  pthread_join (thread_id1, NULL);

  printf ("[%d]end\n",p_pid);
  return 0;

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