From: Ross Morley <ross@tensilica.com>
Cc: gdb@sourceware.org
Subject: Re: RFC: Program Breakpoints
Date: Tue, 31 Mar 2009 00:44:00 -0000 [thread overview]
Message-ID: <49D16764.2040706@tensilica.com> (raw)
In-Reply-To: <49C7BDD6.3060305@tensilica.com>
I'm preparing the simplified version I described earlier for submission.
In stepping over a program break I increment the PC without running the
inferior (in step_1 of infcmd.c - see trimmed post below for context).
Then I update the frame cache and report the stop reason, new PC, etc.
My old pre-6.x implementation used a function that was deprecated in
6.x and recently removed.
What is the proper way to update the frame without the call to
deprecated_update_frame_pc_hack (get_current_frame (), read_pc ());
I tried calling get_frame_pc (get_current_frame ()) and ignoring the result.
That should call frame_pc_unwind (). But the subsequent
print_stack_frame (get_selected_frame (NULL), -1, LOC_AND_ADDRESS);
reports the address of the break to MI, not the incremented PC.
I also tried reinit_frame_cache () and it works OK. Seems drastic though.
For convenience, here's the code snippet from step_1 of infcmd.c:
else if (STOPPED_BY_PROGRAM_BREAKPOINT (&program_break_size) &&
program_break_size != 0 && read_pc() == stop_pc && count > 0)
{
/* "stepi" off program breakpoint: the first step is to just increment
the PC past the break, then there are count-1 steps to go.
Note proceed() won't be called the first time, and on subsequent
steps the PC will already be off the break, so the entire handling
of "stepi" off a program breakpoint is done here. If stopping
after
the break, display location information as for normal_stop. */
count--;
write_pc (read_pc () + program_break_size);
if (count == 0)
{
deprecated_update_frame_pc_hack (get_current_frame (), read_pc
());
if (ui_out_is_mi_like_p (uiout))
{
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
ui_out_field_int (uiout, "thread-id",
pid_to_thread_id (inferior_ptid));
print_stack_frame (get_selected_frame (NULL), -1,
LOC_AND_ADDRESS);
}
else
print_stack_frame (get_selected_frame (NULL), -1, SRC_LINE);
}
}
Thanks,
Ross
Ross Morley wrote:
>
> The Problem
> -----------
>
> When the target program hits a breakpoint of any kind, GDB receives
> a SIGTRAP event. As Aleksander pointed out, if the PC is not in the
> breakpoint table GDB stops because it doesn't know what to do with
> this event. In fact it doesn't always stop. When GDB is stepping
> (for example when a software watchpoint is set) it sees the SIGTRAP
> as a normal step event, so it continues stepping. If the break
> instruction didn't increment the PC, it keeps executing the same
> break instruction forever. This is very frustrating for users (who
> reported this as a bug) because when you have a s/w watchpoint and
> are stepping, execution is expected to be slow, so you wait a long
> time before you realize it's hung.
>
<stuff deleted>
> The Solution
> ------------
>
> The first part is to recognize when you hit a program break.
> The second is to step over it when you want to resume.
>
<stuff deleted>
> Having discovered that it stopped for a program breakpoint, GDB
> is able to report the fact to both the CLI and MI. I also defined
> a gdbarch function to report the meaning of "kind" in an arch-
> specific way. This improves the debugging experience when the
> target uses different kinds of breakpoints to denote different
> reasons for stopping. (However, in the interest of simplicity,
> my revised proposal won't report all that - it is anyway obvious
> from a disassembly if not a symbol associated with the PC; GDB
> itself only needs to know the size to skip the breakpoint).
>
> When the user elects to continue after a program breakpoint,
> GDB increments the PC by the size of the break that was reported
> in the "kind" argument. A gdbarch function handles this. Of
> course it might do nothing if the PC was already advanced.
>
> I haven't discussed all the implementation details here.
> Please see the attached 6.8 based patch for the actual code.
> Note this patch does not pretend to be ready for submission!
>
<stuff deleted>
> Proposed Improved, Simplified Solution
> --------------------------------------
>
> The remote protocol extension would be:
> TAAtrap[:size]
> where ":size" is optional and may only be provided to GDB by the
> target agent if the PC is in fact pointing to the instruction
> that caused the break, and if omitted is taken to be 0.
> GDB will skip the break by PC += size (no effect if size is 0).
> Note it is not necessary to call gdbarch_breakpoint_from_pc().
>
> The gdbarch functions to extract the size and decipher "kind"
> are not needed. The target interface function
> STOPPED_BY_PROGRAM_BREAKPOINT(k)
> becomes
> STOPPED_BY_PROGRAM_BREAKPOINT(size)
> where 'size' is an address in which the size is returned.
>
> We might also want to consider calling it "program trap" and
> keep the term "breakpoint" for things that GDB knows about.
>
>
> Comments are welcome. We at Tensilica would like to see this
> refined and incorporated into mainline GDB.
>
> This can certainly coexist with permanent breakpoints,
> however it is (I think) a bit more general. If the people
> who use permanent breakpoints would care to comment,
> perhaps we can somehow reconcile these into one feature.
>
> Thanks,
> Ross Morley
> Tensilca, Inc.
> ross@tensilica.com
>
>
>diff -urN gdb-6.8-orig/gdb/infcmd.c gdb-6.8-new/gdb/infcmd.c
>--- gdb-6.8-orig/gdb/infcmd.c 2009-03-19 17:29:48.000000000 -0700
>+++ gdb-6.8-new/gdb/infcmd.c 2009-03-20 11:33:21.000000000 -0700
>@@ -696,6 +696,9 @@
> struct frame_info *frame;
> struct cleanup *cleanups = 0;
> int async_exec = 0;
>+/* TENSILICA_LOCAL */
>+ int program_break_kind;
>+/* END TENSILICA_LOCAL */
>
> ERROR_NO_INFERIOR;
>
>@@ -725,6 +728,33 @@
> else
> make_exec_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
> }
>+/* TENSILICA_LOCAL */
>+ else if (STOPPED_BY_PROGRAM_BREAKPOINT (&program_break_kind) &&
>+ read_pc() == stop_pc && count > 0)
>+ {
>+ /* "stepi" off program breakpoint: the first step is to just increment
>+ the PC past the break, then there are count-1 steps to go.
>+ Note proceed() won't be called the first time, and on subsequent
>+ steps the PC will already be off the break, so the entire handling
>+ of "stepi" off a program breakpoint is done here. If stopping after
>+ the break, display location information as for normal_stop. */
>+ count--;
>+ gdbarch_skip_program_breakpoint (current_gdbarch, program_break_kind);
>+ if (count == 0)
>+ {
>+ deprecated_update_frame_pc_hack (get_current_frame (), read_pc ());
>+ if (ui_out_is_mi_like_p (uiout))
>+ {
>+ ui_out_field_string (uiout, "reason", "end-stepping-range");
>+ ui_out_field_int (uiout, "thread-id",
>+ pid_to_thread_id (inferior_ptid));
>+ print_stack_frame (get_selected_frame (NULL), -1, LOC_AND_ADDRESS);
>+ }
>+ else
>+ print_stack_frame (get_selected_frame (NULL), -1, SRC_LINE);
>+ }
>+ }
>+/* END TENSILICA_LOCAL */
>
>
>
>
next prev parent reply other threads:[~2009-03-31 0:44 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-16 17:41 [RFC] stepping over permanent breakpoint Aleksandar Ristovski
2009-03-16 18:22 ` Pedro Alves
2009-03-16 18:55 ` Aleksandar Ristovski
2009-03-16 19:38 ` Pedro Alves
2009-03-16 20:37 ` Aleksandar Ristovski
2009-03-16 18:50 ` Mark Kettenis
2009-03-16 19:04 ` Aleksandar Ristovski
2009-03-23 16:50 ` RFC: Program Breakpoints (was: [RFC] stepping over permanent breakpoint) Ross Morley
2009-03-24 16:57 ` Daniel Jacobowitz
2009-03-24 20:33 ` RFC: Program Breakpoints Ross Morley
2009-03-24 20:40 ` Daniel Jacobowitz
2009-03-24 23:48 ` Pedro Alves
2009-03-25 7:58 ` Mark Kettenis
2009-03-25 13:17 ` Pedro Alves
2009-03-24 23:59 ` Ross Morley
2009-03-31 0:44 ` Ross Morley [this message]
2009-03-31 3:17 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49D16764.2040706@tensilica.com \
--to=ross@tensilica.com \
--cc=gdb@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox