Created attachment 7808 [details] a synthetic example to reproduce the problem with necessary scripts I was able to create a simple program to reproduce the crash. In fact, originally the bug was found when debugging from Eclipse Kepler SP1, that's why it is the MI interface. In the attachment, you can find the following files: main.cpp - simple program source compile - two commands to build main.cpp gdb_bug_test_pretty_print.cmd - pretty print script mi.cmd - MI commands that would make it crash. They use relative paths so it should just run out of the box if you have all the files in the same directory gdb_bug_test - executable if you happen to be able to run (built on suse11 64 bit), otherwise build using compile script
Hello, I stumbled over the same problem as Andrey when trying to use pretty printers from exlipse CDT/gdb MI, which call an external method of a class. Is there any progress on this bug? I would like to help with fixing this bug, as we are also using pretty printers through CDT. However, I have no idea, where to start in the source code. Can anyone give me some hints?
We did a little debugging on our side and have a very local and crude fix for our specific problem, when calling stack-list-locals via the mi interface and using pretty-printers, which call external methods. In our case the internal_error (__FILE__, __LINE__, "unexpected prev_pc status: %d", (int) this_frame->prev_pc.status); error is thrown in frame.c:861 As a fix we throw an a PC not available error, which seems to fix the problem in our case, but isn't the correct solution. In general the bug is related to frame->next getting corrupted during a call to stack.c:read_frame_local. As this function is only called in the MI interface the error seems to be there. If anyone has an idea how to really fix this problem, we can further assist Below you find a stacktrace of our application, which triggers the internal_error: #0 frame_unwind_pc (this_frame=0x30cad80) at frame.c:861 #1 0x000000000074e092 in get_frame_pc (frame=0xfd2ae0) at frame.c:2219 #2 0x000000000074e17c in get_frame_address_in_block (this_frame=0xfd2ae0) at frame.c:2250 #3 0x000000000074e258 in get_frame_address_in_block_if_available (this_frame=0xfd2ae0, pc=0x7fffffffacc8) at frame.c:2314 #4 0x00000000005844ab in get_frame_block (frame=0xfd2ae0, addr_in_block=0x0) at blockframe.c:61 #5 0x00000000006d0ea7 in dwarf_expr_frame_base (baton=0x7fffffffb020, start=0x7fffffffae70, length=0x7fffffffae68) at dwarf2loc.c:351 #6 0x00000000006ce6ac in execute_stack_op (ctx=0x10aca80, op_ptr=0x7fffefff6443 "", op_end=0x7fffefff6443 "") at dwarf2expr.c:953 #7 0x00000000006cd4c5 in dwarf_expr_eval (ctx=0x10aca80, addr=0x7fffefff6440 "\221\360|", len=3) at dwarf2expr.c:363 #8 0x00000000006d503c in dwarf2_evaluate_loc_desc_full (type=0x1c88450, frame=0xfd2ae0, data=0x7fffefff6440 "\221\360|", size=3, per_cu=0x10c36d0, byte_offset=0) at dwarf2loc.c:2211 #9 0x00000000006d5789 in dwarf2_evaluate_loc_desc (type=0x1c88450, frame=0xfd2ae0, data=0x7fffefff6440 "\221\360|", size=3, per_cu=0x10c36d0) at dwarf2loc.c:2395 #10 0x00000000006d787b in locexpr_read_variable (symbol=0x1eaafa0, frame=0xfd2ae0) at dwarf2loc.c:3505 #11 0x00000000005a5f5e in default_read_var_value (var=0x1eaafa0, frame=0xfd2ae0) at findvar.c:433 #12 0x00000000005a6932 in read_var_value (var=0x1eaafa0, frame=0xfd2ae0) at findvar.c:620 #13 0x000000000061acc5 in read_frame_local (sym=0x1eaafa0, frame=0xfd2ae0, argp=0x7fffffffb310) at stack.c:314 #14 0x0000000000519128 in list_args_or_locals (what=locals, values=PRINT_ALL_VALUES, fi=0xfd2ae0, skip_unavailable=0) at ./mi/mi-cmd-stack.c:655 #15 0x0000000000518557 in mi_cmd_stack_list_locals (command=0x1fda3a0 "stack-list-locals", argv=0xf121a0, argc=1) at ./mi/mi-cmd-stack.c:263 #16 0x00000000005205df in mi_cmd_execute (parse=0x25de800) at ./mi/mi-main.c:2254 #17 0x000000000051fc14 in captured_mi_execute_command (uiout=0x10ceec0, context=0x25de800) at ./mi/mi-main.c:1989 #18 0x0000000000520011 in mi_execute_command (cmd=0x2240d70 "36-stack-list-locals --thread 1 --frame 0 1", from_tty=1) at ./mi/mi-main.c:2117 #19 0x000000000051a51f in mi_execute_command_wrapper (cmd=0x2240d70 "36-stack-list-locals --thread 1 --frame 0 1") at ./mi/mi-interp.c:304 #20 0x000000000051a56b in mi_execute_command_input_handler (cmd=0x2240d70 "36-stack-list-locals --thread 1 --frame 0 1") at ./mi/mi-interp.c:334 #21 0x0000000000630a7e in gdb_readline2 (client_data=0x0) at event-top.c:773 #22 0x000000000063023e in stdin_event_handler (error=0, client_data=0x0) at event-top.c:432 #23 0x000000000062eee1 in handle_file_event (file_ptr=0x142c470, ready_mask=1) at event-loop.c:657 #24 0x000000000062f405 in gdb_wait_for_event (block=0) at event-loop.c:772 #25 0x000000000062e429 in gdb_do_one_event () at event-loop.c:284 #26 0x000000000062e4f5 in start_event_loop () at event-loop.c:334 #27 0x000000000051a5ea in mi_command_loop (data=0x10d0580) at ./mi/mi-interp.c:367 #28 0x0000000000626e2a in current_interp_command_loop () at interps.c:317 #29 0x0000000000627990 in captured_command_loop (data=0x0) at main.c:321 #30 0x0000000000623af3 in catch_errors (func=0x627975 <captured_command_loop>, func_args=0x0, errstring=0xa40cbe "", mask=RETURN_MASK_ALL) at exceptions.c:237 #31 0x0000000000628ec8 in captured_main (data=0x7fffffffba70) at main.c:1149 ---Type <return> to continue, or q <return> to quit--- #32 0x0000000000623af3 in catch_errors (func=0x627dac <captured_main>, func_args=0x7fffffffba70, errstring=0xa40cbe "", mask=RETURN_MASK_ALL) at exceptions.c:237 #33 0x0000000000628ef1 in gdb_main (args=0x7fffffffba70) at main.c:1157 #34 0x000000000046d16b in main (argc=3, argv=0x7fffffffbb78) at gdb.c:32
> In general the bug is related to frame->next getting corrupted If it's corruption, Valgrind probably helps. Does it still happen with 7.11? What about master?
Created attachment 9289 [details] patch
It seems we found a quite good solution now and finally understood the problem. In the list_args_or_locals function of mi-cmd-stack.c all locals of the current frame_info *fi are printed. However when mi-cmd-stack.c:661 list_arg_or_local is called the frame cache gets cleared, if the inferior is run by a pretty-printer. Afterward *fi is still used without a check that it is invalid. Therefoe we set fi again using get_current_frame() This fix also solves the original problem posted by Andrey. Can somebody validate the attached patch?
Bah, pretty-printers should really not be running the inferior... :-/ Consider for example debugging core dumps... I'd assume that this code will be printing args of some other frame not the current one (current == frame #0 by definition). Should probably save the frame's frame_id, and then try to restore it with find_frame_by_id, instead of assuming get_current_frame() is the right frame. It'd be very good to add a testcase to the testsuite to cover this. Take a look at: https://sourceware.org/gdb/wiki/ContributionChecklist
Dup. *** This bug has been marked as a duplicate of bug 28856 ***