[push] Revert old nexti prologue check and eliminate in_prologue

Pedro Alves
2014-11-07T14:45:45Z

On 10/24/2014 04:12 PM, Ulrich Weigand wrote:
> Pedro Alves wrote:
>
>> Subject: [PATCH] Revert nexti prologue check
>>
>> From Fernando Nasser:
>> * infrun.c (handle_inferior_event): Handle "nexti" inside function
>> prologues.
>
> This makes sense to me. Minor nit: please also remove the comment
>
>> /* Also, maybe we just did a "nexti" inside a prolog, so we
>> thought it was a subroutine call but it was not. Stop as
>> well. FENN */

Done, and pushed now.

Thanks.

From b7a084bebe979a4743540349025561ce82208843 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 7 Nov 2014 13:53:01 +0000
Subject: [PATCH] Revert old nexti prologue check and eliminate in_prologue

The in_prologue check in the nexti code is obsolete; this commit
removes that, and then removes the in_prologue function as nothing
else uses it.

Looking at the code in GDB that makes use in_prologue, all we find is
this one caller:

if ((ecs->event_thread->control.step_over_calls == STEP_OVER_NONE)
|| ((ecs->event_thread->control.step_range_end == 1)
&& in_prologue (gdbarch, ecs->event_thread->prev_pc,
ecs->stop_func_start)))
{
/* I presume that step_over_calls is only 0 when we're
supposed to be stepping at the assembly language level
("stepi"). Just stop. */
/* Also, maybe we just did a "nexti" inside a prolog, so we
thought it was a subroutine call but it was not. Stop as
well. FENN */
/* And this works the same backward as frontward. MVS */
end_stepping_range (ecs);
return;
}

This was added by:

commit 100a02e1deec2f037a15cdf232f026dc79763bf8
...
From Fernando Nasser:
* infrun.c (handle_inferior_event): Handle "nexti" inside function
prologues.

The mailing list thread is here:

https://sourceware.org/ml/gdb-patches/2001-01/msg00047.html

Not much discussion there, and no test, but looking at the code around
what was patched in that revision, we see that the checks that detect
whether the program has just stepped into a subroutine didn't rely on
the unwinders at all back then.

From 'git show 100a02e1:gdb/infrun.c':

if (stop_pc == ecs->stop_func_start /* Quick test */
|| (in_prologue (stop_pc, ecs->stop_func_start) &&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name))
|| IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name)
|| ecs->stop_func_name == 0)
{
/* It's a subroutine call. */

if ((step_over_calls == STEP_OVER_NONE)
|| ((step_range_end == 1)
&& in_prologue (prev_pc, ecs->stop_func_start)))
{
/* I presume that step_over_calls is only 0 when we're
supposed to be stepping at the assembly language level
("stepi"). Just stop. */
/* Also, maybe we just did a "nexti" inside a prolog,
so we thought it was a subroutine call but it was not.
Stop as well. FENN */
stop_step = 1;
print_stop_reason (END_STEPPING_RANGE, 0);
stop_stepping (ecs);
return;
}

Stripping the IN_SOLIB_RETURN_TRAMPOLINE checks for simplicity, we had:

if (stop_pc == ecs->stop_func_start /* Quick test */
|| in_prologue (stop_pc, ecs->stop_func_start)
|| ecs->stop_func_name == 0)
{
/* It's a subroutine call. */

That is, detecting a subroutine call was based on prologue detection
back then. So the in_prologue check in the current tree only made
sense back then as it was undoing a bad decision the in_prologue check
that used to exist above did.

Today, the check for a subroutine call relies on frame ids instead,
which are stable throughout the function. So we can just remove the
in_prologue check for nexti, and the whole in_prologue function along
with it.

Tested on x86_64 Fedora 20, and also by nexti-ing manually a prologue.

gdb/
2014-11-07 Pedro Alves <palves@redhat.com>

* infrun.c (process_event_stop_test) <subroutine check>: Don't
check if we did a "nexti" inside a prologue.
* symtab.c (in_prologue): Delete function.
* symtab.h (in_prologue): Delete declaration.
---
gdb/ChangeLog | 7 ++++++
gdb/infrun.c | 8 +------
gdb/symtab.c | 73 -----------------------------------------------------------
gdb/symtab.h | 3 ---
4 files changed, 8 insertions(+), 83 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f75a5ba..0a8bee8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-07 Pedro Alves <palves@redhat.com>
+
+ * infrun.c (process_event_stop_test) <subroutine check>: Don't
+ check if we did a "nexti" inside a prologue.
+ * symtab.c (in_prologue): Delete function.
+ * symtab.h (in_prologue): Delete declaration.
+
2014-11-06 Doug Evans <xdje42@gmail.com>

* symtab.h (lookup_global_symbol): Improve function comment.
diff --git a/gdb/infrun.c b/gdb/infrun.c
index b950b74..b2e182f 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -5004,17 +5004,11 @@ process_event_stop_test (struct execution_control_state *ecs)
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepped into subroutine\n");

- if ((ecs->event_thread->control.step_over_calls == STEP_OVER_NONE)
- || ((ecs->event_thread->control.step_range_end == 1)
- && in_prologue (gdbarch, ecs->event_thread->prev_pc,
- ecs->stop_func_start)))
+ if (ecs->event_thread->control.step_over_calls == STEP_OVER_NONE)
{
/* I presume that step_over_calls is only 0 when we're
supposed to be stepping at the assembly language level
("stepi"). Just stop. */
- /* Also, maybe we just did a "nexti" inside a prolog, so we
- thought it was a subroutine call but it was not. Stop as
- well. FENN */
/* And this works the same backward as frontward. MVS */
end_stepping_range (ecs);
return;
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2aae04c..df974bf 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2954,79 +2954,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
}
}

-/* Determine if PC is in the prologue of a function. The prologue is the area
- between the first instruction of a function, and the first executable line.
- Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
-
- If non-zero, func_start is where we think the prologue starts, possibly
- by previous examination of symbol table information. */
-
-int
-in_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR func_start)
-{
- struct symtab_and_line sal;
- CORE_ADDR func_addr, func_end;
-
- /* We have several sources of information we can consult to figure
- this out.
- - Compilers usually emit line number info that marks the prologue
- as its own "source line". So the ending address of that "line"
- is the end of the prologue. If available, this is the most
- reliable method.
- - The minimal symbols and partial symbols, which can usually tell
- us the starting and ending addresses of a function.
- - If we know the function's start address, we can call the
- architecture-defined gdbarch_skip_prologue function to analyze the
- instruction stream and guess where the prologue ends.
- - Our `func_start' argument; if non-zero, this is the caller's
- best guess as to the function's entry point. At the time of
- this writing, handle_inferior_event doesn't get this right, so
- it should be our last resort. */
-
- /* Consult the partial symbol table, to find which function
- the PC is in. */
- if (! find_pc_partial_function (pc, NULL, &func_addr, &func_end))
- {
- CORE_ADDR prologue_end;
-
- /* We don't even have minsym information, so fall back to using
- func_start, if given. */
- if (! func_start)
- return 1; /* We *might* be in a prologue. */
-
- prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
-
- return func_start <= pc && pc < prologue_end;
- }
-
- /* If we have line number information for the function, that's
- usually pretty reliable. */
- sal = find_pc_line (func_addr, 0);
-
- /* Now sal describes the source line at the function's entry point,
- which (by convention) is the prologue. The end of that "line",
- sal.end, is the end of the prologue.
-
- Note that, for functions whose source code is all on a single
- line, the line number information doesn't always end up this way.
- So we must verify that our purported end-of-prologue address is
- *within* the function, not at its start or end. */
- if (sal.line == 0
- || sal.end <= func_addr
- || func_end <= sal.end)
- {
- /* We don't have any good line number info, so use the minsym
- information, together with the architecture-specific prologue
- scanning code. */
- CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
-
- return func_addr <= pc && pc < prologue_end;
- }
-
- /* We have line number info, and it looks good. */
- return func_addr <= pc && pc < sal.end;
-}
-
/* Given PC at the function's start address, attempt to find the
prologue end using SAL information. Return zero if the skip fails.

diff --git a/gdb/symtab.h b/gdb/symtab.h
index 9b3ea80..d78b832 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1347,9 +1347,6 @@ extern enum language deduce_language_from_filename (const char *);

/* symtab.c */

-extern int in_prologue (struct gdbarch *gdbarch,
- CORE_ADDR pc, CORE_ADDR func_start);
-
extern CORE_ADDR skip_prologue_using_sal (struct gdbarch *gdbarch,
CORE_ADDR func_addr);

--
1.9.3