This is the mail archive of the gdb@sourceware.org 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]

Re: Stepping of multithreaded application


On Thursday 12 May 2011 11:44:50, Tomas Martinec wrote:
> >> That is not supported in the virtual machine
> >> and the machine responds so. I believe not supporting the Hc0 command
> >> is not wrong for the virtual machine.
> >
> > IMO, it's wrong.  But I don't think it'd make a difference, unless
> > the target gives preference to the already/previously selected
> > Hg/c thread.
> 
> > In any case, you should really teach your VM about the vCont
> > packet instead of 'Hc'/'s'/'c'.
> 
> I will implement both the Hc0 and vCont in the virtual machine. But at
> first I will try to make just the Hc/s/c commands working.
> 
> > Please try the patch below.  It's "any_thread_ptid" that causes "Hc0".
> > If we're stepping, obviously we need to step the correct thread, not
> > a random one.  I don't really understand how this hasn't been a
> > problem before.
> 
> There was another problem after applying the patch. The GDB resumed
> the thread 1 after the thread 3 stepped. I think I have made a fix:
> 
> --- infrun_old.c	2010-08-31 21:31:23.000000000 +0200
> +++ infrun.c	2011-05-12 12:20:15.000000000 +0200
> @@ -3513,6 +3513,8 @@
>  	      singlestep_breakpoints_inserted_p = 0;
>  	    }
> 
> +	  ecs->event_thread->trap_expected = 0;
> +
>  	  /* Note: We do not call context_switch at this point, as the
>  	     context is already set up for stepping the original thread.  */
>  	  switch_to_thread (deferred_step_ptid);
> 
> The trap_expected flag of the thread 1 was not cleared after the step
> of thread 1. Therefore the code has run into the following branch
> during step handling of the thread 3:

This makes sense.  However ...

> 
> infrun.c: line 4182
> 
>   /* In all-stop mode, if we're currently stepping but have stopped in
>      some other thread, we need to switch back to the stepped thread.  */
>   if (!non_stop)
>     {
>       struct thread_info *tp;
> 
>       tp = iterate_over_threads (currently_stepping_or_nexting_callback,
> 				 ecs->event_thread);
>       if (tp)
> 	{
>               // this branch is done, which is wrong; it is done,
> because the thread 1
>               // has trap_expected set and therefore the thread is
> considered to be stepping
>               //
>               // the thread 1 is resumed in this branch; in my case
> the thread 3 never finishes stepping

When I try this (without your patch on x86_64-linux native, I see
is:

Breakpoint 1, thread0 (arg=0x0) at loop.c:39
39              (*myp) ++;
(gdb) info threads 
  Id   Target Id         Frame 
  3    Thread 0x7ffff703a700 (LWP 27787) "loop" 0x00007ffff78e620d in nanosleep () from /lib/libc.so.6
* 2    Thread 0x7ffff783b700 (LWP 27786) "loop" thread0 (arg=0x0) at loop.c:39
  1    Thread 0x7ffff7fd5700 (LWP 27783) "loop" 0x00007ffff7bc7285 in pthread_join () from /lib/libpthread.so.0
(gdb) t 3
[Switching to thread 3 (Thread 0x7ffff703a700 (LWP 27787))]
#0  0x00007ffff78e620d in nanosleep () from /lib/libc.so.6
(gdb) n
infrun: clear_proceed_status_thread (Thread 0x7ffff703a700 (LWP 27787))
infrun: clear_proceed_status_thread (Thread 0x7ffff783b700 (LWP 27786))
infrun: clear_proceed_status_thread (Thread 0x7ffff7fd5700 (LWP 27783))
Single stepping until exit from function nanosleep,
which has no line number information.
infrun: proceed (addr=0xffffffffffffffff, signal=144, step=1)
thread_function1: 8
thread_function0: 10
infrun: resume (step=1, signal=0), trap_expected=1
infrun: wait_for_inferior ()
infrun: target_wait (-1, status) =
infrun:   27783 [Thread 0x7ffff783b700 (LWP 27786)],
infrun:   status->kind = stopped, signal = SIGTRAP
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x400741
infrun: handling deferred step
infrun: resume (step=1, signal=0), trap_expected=0
infrun: prepare_to_wait
infrun: target_wait (-1, status) =
infrun:   27783 [Thread 0x7ffff703a700 (LWP 27787)],
infrun:   status->kind = stopped, signal = SIGTRAP
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x7ffff78e620d
infrun: switching back to stepped thread
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This is indeed wrong.

infrun: Switching context from Thread 0x7ffff703a700 (LWP 27787) to Thread 0x7ffff783b700 (LWP 27786)
infrun: resume (step=0, signal=0), trap_expected=0

We end up continuing all threads (turn on 'set debug lin-lwp'
to get more debug detail), not stepping or continuing
a single thread.  This `resume' call clears "trap_expected",
and everything happens to work.

I imagine you're seeing a 'Hc1', 'c', and only continuing
thread 1 instead of all threads?  This is part of the
ambiguity with Hc/c/s that vCont fixes...

> The debugging seems to be fine after applying my fix. Still I think
> somebody more familiar with the GDB should review it.

I'll test and apply your fix if nothing turns up regardless.

-- 
Pedro Alves


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