GDB Frame Filter - handling corrupt stack

Simeon S simeon.simeonov.s@gmail.com
Tue Sep 9 21:37:00 GMT 2014


Hi Phil,

Thanks for the response. I've been able to reproduce this issue with
just the following python code which just returns the iterator
untouched:


    import gdb

    class InlineFilter():
        def __init__(self):
            self.name = "InlinedFrameFilter"
            self.priority = 100
            self.enabled = True
            gdb.frame_filters[self.name] = self

        def filter(self, frame_iter):
            return frame_iter

    ff = InlineFilter()


When my program is loaded, it creates a new thread and does a longjmp
so I suspect gdb will not be able to see the stack before the jump
(but this part of the stack is of no interest). The corrupt stack when
debugging my program is probably not something gdb can handle and in
general doesn't cause much problems...until today that is. Anyway, my
first thought was that this is a bug in gdb - a corner case. It would
be a good idea if gdb handles this rare case gracefully - print a
message and continue with the debug session.


I've done a bit of debugging and below is my short debug session. I
have gdb 7.8 as the inferior of gdb 7.8 which has my program as its
inferior (gdb-----|gdb------|prog). When the inferior gdb crashes, the
following backtrace is shown:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00000000005b0b86 in do_my_cleanups (pmy_chain=0xd0ede0
<cleanup_chain>, old_chain=0x74261b0) at cleanups.c:155
#2  0x0000000000530a64 in py_print_args (filter=0x7ffff0ed6978,
out=0x14aa3d0, args_type=CLI_SCALAR_VALUES, frame=0x902b800) at
./python/py-framefilter.c:987
#3  0x0000000000531226 in py_print_frame (filter=0x7ffff0ed6978,
flags=7, args_type=CLI_SCALAR_VALUES, out=0x14aa3d0, indent=0,
levels_printed=0x41a7440) at ./python/py-framefilter.c:1236
#4  0x0000000000531a54 in gdbpy_apply_frame_filter (extlang=0x8ba080
<extension_language_python>, frame=0xe01a40, flags=7,
args_type=CLI_SCALAR_VALUES, out=0x14aa3d0, frame_low=0,
frame_high=-1) at ./python/py-framefilter.c:1534
#5  0x0000000000624428 in apply_ext_lang_frame_filter (frame=0xe01a40,
flags=7, args_type=CLI_SCALAR_VALUES, out=0x14aa3d0, frame_low=0,
frame_high=-1) at extension.c:553
#6  0x000000000061e3de in backtrace_command_1 (count_exp=0x0,
show_locals=0, no_filters=0, from_tty=1) at stack.c:1801
#7  0x000000000061e82b in backtrace_command (arg=0x0, from_tty=1) at
stack.c:1916
#8  0x00000000004fbf43 in do_cfunc (c=0xdedbf0, args=0x0, from_tty=1)
at ./cli/cli-decode.c:107
#9  0x00000000004feec5 in cmd_func (cmd=0xdedbf0, args=0x0,
from_tty=1) at ./cli/cli-decode.c:1886
#10 0x000000000072fba0 in execute_command (p=0xd451c2 "", from_tty=1)
at top.c:462
#11 0x0000000000630ab0 in command_handler (command=0xd451c0 "bt") at
event-top.c:433
#12 0x0000000000631063 in command_line_handler (rl=0x7e3a690 "") at
event-top.c:630
#13 0x0000000000791c12 in rl_callback_read_char () at callback.c:220
#14 0x00000000006305ec in rl_callback_read_char_wrapper
(client_data=0x0) at event-top.c:167
#15 0x00000000006309c2 in stdin_event_handler (error=0,
client_data=0x0) at event-top.c:373
#16 0x000000000062f5b7 in handle_file_event (data=...) at event-loop.c:766
#17 0x000000000062ea8c in process_event () at event-loop.c:343
#18 0x000000000062eb53 in gdb_do_one_event () at event-loop.c:407
#19 0x000000000062eba3 in start_event_loop () at event-loop.c:432
#20 0x000000000063061e in cli_command_loop (data=0x0) at event-top.c:182
#21 0x0000000000626961 in current_interp_command_loop () at interps.c:328
#22 0x0000000000627b0e in captured_command_loop (data=0x0) at main.c:302
#23 0x0000000000623811 in catch_errors (func=0x627af3
<captured_command_loop>, func_args=0x0, errstring=0x91759b "",
mask=RETURN_MASK_ALL) at exceptions.c:506
#24 0x0000000000629054 in captured_main (data=0x7fffffffe7d0) at main.c:1155
#25 0x0000000000623811 in catch_errors (func=0x627ee8 <captured_main>,
func_args=0x7fffffffe7d0, errstring=0x91759b "", mask=RETURN_MASK_ALL)
at exceptions.c:506
#26 0x000000000062907d in gdb_main (args=0x7fffffffe7d0) at main.c:1163
#27 0x0000000000462d3d in main (argc=1, argv=0x7fffffffe8d8) at gdb.c:33
(gdb) frame 1
#1  0x00000000005b0b86 in do_my_cleanups (pmy_chain=0xd0ede0
<cleanup_chain>, old_chain=0x74261b0) at cleanups.c:155
155          (*ptr->function) (ptr->arg);
(gdb) list
150      struct cleanup *ptr;
151
152      while ((ptr = *pmy_chain) != old_chain)
153        {
154          *pmy_chain = ptr->next;    /* Do this first in case of
recursion.  */
155          (*ptr->function) (ptr->arg);
156          if (ptr->free_arg)
157        (*ptr->free_arg) (ptr->arg);
158          xfree (ptr);
159        }
(gdb) info locals
ptr = 0x8f8960 <sentinel_cleanup>
(gdb) p *pmy_chain
$1 = (struct cleanup *) 0x0
(gdb) p *ptr
$2 = {next = 0x0, function = 0x0, free_arg = 0x0, arg = 0x0}
(gdb) p old_chain
$3 = (struct cleanup *) 0x74261b0
(gdb) p *old_chain
$4 = {next = 0x6adca20, function = 0x76dbce <xfree>, free_arg = 0x0,
arg = 0x9c47f00}
(gdb)


Let me know what you need here - I can provide support.

Simeon

On 9 September 2014 16:48, Phil Muldoon <pmuldoon@redhat.com> wrote:
> On 09/09/14 13:26, Simeon S wrote:
>
>
> It's a fairly simple filter, so I don't see much wrong with that.
>
>>
>> When the gdb "backtrace" command is issued, frames are decorated
>> followed by a gdb crash. This is what the last output from gdb is:
>>
>>     UNIX ERR:tcsetattr:Input/output error
>>     Segmentation fault (core dumped)
>
> I'd love to see a backtrace of this.  It is not related to your issue,
> but it is a bug in the frame filters.  It should print the error
> message below:
>
>> The stack seems to be corrupt which is what I suspect is causing the
>> crash. If the frame filter is disabled, the last line of the
>> "backtrace" command is:
>>
>>     Backtrace stopped: previous frame inner to this frame (corrupt stack?)
>
> Yeah at this point the stack looks clobbered, or some kind of bug
> internal to GDB has occurred.
>
>> I haven't looked into why the stack is corrupt - all the frames of
>> interest to me are there.  Is there a way to catch this condition to
>> avoid crashing? I am not interested in any of the corrupt frames -
>> what is in the stack is enough.
>
> No not really.  Someone else may have an idea.
>
>> I guess I am looking for a mechanism to stop gdb iterating over
>> further frames if it detects a corrupt/invalid frame.  The
>> documentation does say that gdb has to iterate over all stack frames
>> though.
>
> Even though the documentation does indeed say that, you can always
> slice/trim the iterator that is handed to the frame filter and return
> the sliced iterator.  The trick is finding which frame would be the
> corrupted one and slicing appropriately.  See the itertools Python
> module for iterator tools (including slicing).
>
> Cheers
>
> Phil
>
>



More information about the Gdb mailing list