Re: Fix a crash when stepping and unwinding fails

Mark Kettenis
2006-02-21T20:15:58Z

> Date: Mon, 20 Feb 2006 17:03:31 -0500
> From: Daniel Jacobowitz <drow@false.org>
>
> This patch stops GDB from segfaulting when we step into a function,
> but can not unwind back out of the function. We would previously
> call get_prev_frame, which would return NULL, and then try to
> get_frame_pc (NULL).
>
> Now we'll issue this error instead, and stop stepping:
>
> Could not step out of the function at 0x80144400 - unwinding failed
>
> It's still not great, but at least it's an improvement over crashing.
> It is reasonably likely that we've just stepped over a standard
> function call, and that consequentially the function return
> address is in the standard place for the architecture; in fact,
> GDB used to have a hook for this, before the frame overhaul:
> SAVED_PC_AFTER_CALL. But it's gone now and there's no easy analogue,
> and it was never 100% reliable anyway. So unfortunately, if we
> single-step out to an address that we can't find a way to unwind from,
> we'll stop instead of stepping out.

How can this happen? Both affected calls to
insert_step_resume_breakpoint_at_frame() are in the same

if (frame_id_eq (frame_unwind_id (get_current_frame ()), step_frame_id))
{

block. Assuming that step_frame_id isn't equal to null_frame_id, this
means that we *can* unwind. Seems like the problem is that the code
uses get_prev_frame(), which can return NULL, even if we could unwind,
for example when we try to unwind past main. Looks to me the real bug
here is that we're using get_prev_frame(). The right solution is
probably to use frame_pc_unwind(), and insert a the step resume
breakpoint there. That should never fail.

This would probably demand us to introduce
insert_step_resume_breakpoint_at_pc(), and we could probably eliminate
insert_step_resume_breakpoint_at_frame() altogether. An alternative
would be to export get_prev_name_1() from frame.c (giving it a more
useful name).

I must say, I don't really liked the way you changed the
insert_step_resume_breakpoint_at_frame() interface. That extra
USE_PREVIOUS argument is really awkward, and made the function name
rather non-sensible.

Mark