This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [rfc] Do not call read_pc in startup_inferior
- From: Pedro Alves <pedro at codesourcery dot com>
- To: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- Cc: gdb-patches at sourceware dot org, Daniel Jacobowitz <drow at false dot org>
- Date: Thu, 30 Apr 2009 16:55:35 +0100
- Subject: Re: [rfc] Do not call read_pc in startup_inferior
- References: <200904301425.n3UEPMhk019694@d12av02.megacenter.de.ibm.com>
On Thursday 30 April 2009 15:25:17, Ulrich Weigand wrote:
> Pedro Alves wrote:
>
> > Actually, currently it is hard to stop at the entry point
> > in most targets. `proceed' will step over a breakpoint set right
> > at the entry point exactly due to this stop_pc == current pc, even
> > if it was never hit. This leads to people using the "set breakpoint
> > at `entry point' + 1, instead of `entry point'" trick.
> >
> > Maybe we should make run_command_1
> > call `proceed (current_pc, TARGET_SIGNAL_0, 0)' instead of
> > `proceed (-1, TAR...)'. This would (partially) fix the bpkt at
> > entry issue, while also making sure that `proceed' isn't faced with a
> > completely random random stop_pc if we pass it -1.
>
> I see. It seems "stop_pc" isn't really the proper mechanism for this.
> (See also the problems with skipping breakpoints in multi-threaded
> applications that Doug Evans has been working on ...)
Yeah, I'm also interested in this for multi-process as well.
> What would you think about the following replacement for stop_pc:
Before going further, I don't think you should hold on your current
patch?
> - Per thread, maintain a "last stop reason" state that identifies
> *where* and *why* this thread stopped.
> - We skip a breakpoint whenever we're about to restart a thread and
> its "last stop reason" is "breakpoint" with an address equal to
> the restart address (and there's still a breakpoint at this location).
This logic with per-thread "last stop reason is breakpoint"
changes the current behaviour, in the wrong direction, I believe.
I don't think "breakpoint" or not is the correct check. Consider:
1. (gdb) step
2. (gdb) step
3. (gdb) break
4. (gdb) continue
At 3. the current thread was not stopped at a breakpoint, yet,
in 4., `proceed' is expected to skip over the breakpoint you've
just set.
Here's a multi-threaded example, in all-stop mode:
(gdb) break foo
breakpoint 1
(gdb) continue
stop at breakpoint 1, thread 1
(gdb) thread 2
(gdb) break
breakpoint 2
(gdb) continue
stop at breakpoint 2, thread 2
Currently, GDB will switch to thread 1, single step (this is
the prepare_to_proceed logic), and then resume. `proceed' is
not involved in the latter resume, so we stop at 'breakpoint 2'.
If we had a per-thread stop_pc, we'd be able to make this
behave identically to the example below. Compare the above
to:
(gdb) break foo
breakpoint 1
(gdb) continue
stop at breakpoint 1, thread 1
(gdb) step <<<<<<<< (move out of the breakpoint)
(gdb) thread 2
(gdb) break
breakpoint 2
(gdb) continue
<doesn't stop at breakpoint 2, because proceed steps over
break 2>
> - In "info program", display the last stop reason of the current
> thread (or maybe all threads?).
I think the intent of "info program" is to show the last stop reason,
no matter what thread you have selected. I think "info threads" would
be a good place to show last stop reason of all threads, especially
if you think of non-stop mode. Most IDE's I know that show last
stop reason, put it next to the description of each thread, in the
thread tree/list.
> - In solib-sunos.c, just use regcache_read_pc.
Sounds good.
> > (I believe there are other problems that make GDB ignore
> > breakpoints set at the entry point, e.g., if it happens to
> > be the same place we have a BPSTAT_WHAT_CHECK_SHLIBS breakpoint.)
>
> Hmm, if we have two breakpoints at the same address, one that is
> supposed to silently restart, and one that is supposed to be
> reported to the user, shouldn't the second one always "win"?
Close, but not quite. Yes, we should stop for the second one, but,
we should still handle the BPSTAT_WHAT_CHECK_SHLIBS shlibs checking.
Currently, shlib event gets picked over a user breakpoint, and infrun.c
immediatelly resumes the target after hanling BPSTAT_WHAT_CHECK_SHLIBS.
The root problem here is that the shlib event breakpoint handling
should *not* be mutually exclusive with other breakpoints handling,
but, it is currently. Funny enough, Doug has just tripped on
this: http://sourceware.org/ml/gdb-patches/2009-04/msg00801.html
In his case, when stopping for a shlib event, and if the watchpoint's
value has changed simultaneously,
bpstat_stop_status->bpstat_check_watchpoint->watchpoint_check
updates the watchpoint value, but, GDB resumes the inferior immediately,
even though there was a watchpoint hit to report... Exactly the same
problem.
--
Pedro Alves