[PATCH] Handle dprintf argument evaluation errors better (PR gdb/16551)
Simon Marchi
simon.marchi@polymtl.ca
Wed Jun 27 14:32:00 GMT 2018
On 2018-06-13 16:01, Simon Marchi wrote:
> The current behavior when GDB fails to evaluate the arguments of a
> dynamic printf is not very good.
>
> There was a previous attempt at fixing this here, but it did not went
> through:
> https://sourceware.org/ml/gdb-patches/2015-02/msg00258.html
>
> The issue can be reproduced by setting a dprintf referring to a
> variable
> that doesn't exist or that triggers a memory error:
>
> dprintf hello, "hello %d\n", *((int*)0)
> dprintf hello, "hello %d\n", doesnt_exist
>
> When an evaluation error occurs, an error is thrown at the stack trace
> shown below and is caught in start_event_loop. This leaves things in a
> relatively bad shape:
>
> - Printing the error in start_event_loop causes GDB to receive a
> SIGTTOU
> signal, because the terminal is still owned by the inferior at that
> point.
> - There is an error message (e.g. No symbol "foo" in current context)
> and you are back to the GDB prompt, but nothing gives a clue about
> the
> context of the error.
> - The thread that hit the dprintf is stopped. If in all-stop mode on
> an
> all-stop-on-top-of-non-stop target, you end up with a single thread
> stopped and the others running, which is not good.
> - With MI, the thread(s) is/are stopped but no *stopped event is sent,
> so frontends still show it as running.
>
> I actually think it is nice that the program stops if there is an
> error, so you can notice the problem and fix it. It just needs to be
> handled better. This patch makes GDB catch the evaluation error in the
> dprintf_after_condition_true function, and sets bpstat::stop to 1/true,
> so that the dprintf will cause a stop similar to a breakpoint hit. The
> dprintf_print_it function defines how a "dprintf error hit" is printed.
> The result looks like this:
>
> (gdb) c
> Continuing.
>
> Dprintf 2, failed to evaluate: No symbol "lalala" in current context.
> foo (n=1) at
> /home/emaisin/src/binutils-gdb/gdb/testsuite/gdb.base/dprintf-error.c:30
>
> When using MI, the stop is communicated using a new reason
> "dprintf-error", and the error-message field gives the text of the
> exception:
>
> *stopped,reason="dprintf-error",bkptno="2",error-message="No symbol
> \"lalala\" in current context.",frame=...
>
> #0 error (fmt=0x12bad88 "No symbol \"%s\" in current context.") at
> /home/emaisin/src/binutils-gdb/gdb/common/errors.c:39
> #1 0x00000000006f5d49 in c_yyparse () at
> /home/emaisin/src/binutils-gdb/gdb/c-exp.y:1090
> #2 0x00000000006fc082 in c_parse (par_state=0x7ffd3ed91c50) at
> /home/emaisin/src/binutils-gdb/gdb/c-exp.y:3273
> #3 0x0000000000979d88 in parse_exp_in_context_1
> (stringptr=0x7ffd3ed91e00, pc=0, block=0x0, comma=1, void_context_p=0,
> out_subexp=0x0) at /home/emaisin/src/binutils-gdb/gdb/parse.c:1205
> #4 0x0000000000979aae in parse_exp_in_context
> (stringptr=0x7ffd3ed91e00, pc=0, block=0x0, comma=1, void_context_p=0,
> out_subexp=0x0) at /home/emaisin/src/binutils-gdb/gdb/parse.c:1108
> #5 0x0000000000979a2d in parse_exp_1 (stringptr=0x7ffd3ed91e00,
> pc=0, block=0x0, comma=1) at
> /home/emaisin/src/binutils-gdb/gdb/parse.c:1099
> #6 0x000000000089ec1d in parse_to_comma_and_eval
> (expp=0x7ffd3ed91e00) at /home/emaisin/src/binutils-gdb/gdb/eval.c:126
> #7 0x0000000000981a84 in ui_printf (arg=0x307f377 "\"hello %d\\n\",
> lalala", stream=0x2f34b90) at
> /home/emaisin/src/binutils-gdb/gdb/printcmd.c:2464
> #8 0x000000000098212a in printf_command (arg=0x307f377 "\"hello
> %d\\n\", lalala", from_tty=0) at
> /home/emaisin/src/binutils-gdb/gdb/printcmd.c:2580
> #9 0x0000000000603808 in do_const_cfunc (c=0x2ee6b00,
> args=0x307f377 "\"hello %d\\n\", lalala", from_tty=0) at
> /home/emaisin/src/binutils-gdb/gdb/cli/cli-decode.c:106
> #10 0x0000000000606900 in cmd_func (cmd=0x2ee6b00, args=0x307f377
> "\"hello %d\\n\", lalala", from_tty=0) at
> /home/emaisin/src/binutils-gdb/gdb/cli/cli-decode.c:1857
> #11 0x0000000000a61415 in execute_command (p=0x307f38a "a",
> from_tty=0) at /home/emaisin/src/binutils-gdb/gdb/top.c:630
> #12 0x00000000006106f6 in execute_control_command_1 (cmd=0x2fd6f30,
> from_tty=0) at /home/emaisin/src/binutils-gdb/gdb/cli/cli-script.c:525
> #13 0x0000000000610d2a in execute_control_command (cmd=0x2fd6f30,
> from_tty=0) at /home/emaisin/src/binutils-gdb/gdb/cli/cli-script.c:694
> #14 0x000000000077e83f in bpstat_do_actions_1 (bsp=0x7ffd3ed922e8)
> at /home/emaisin/src/binutils-gdb/gdb/breakpoint.c:4433
> #15 0x00000000007920e1 in dprintf_after_condition_true
> (bs=0x2fe9260) at
> /home/emaisin/src/binutils-gdb/gdb/breakpoint.c:13035
> #16 0x000000000078057c in bpstat_stop_status (aspace=0x2f169e0,
> bp_addr=4195559, ptid=..., ws=0x7ffd3ed927a0, stop_chain=0x2fe9260) at
> /home/emaisin/src/binutils-gdb/gdb/breakpoint.c:5460
> #17 0x0000000000908760 in handle_signal_stop (ecs=0x7ffd3ed92780) at
> /home/emaisin/src/binutils-gdb/gdb/infrun.c:5946
> #18 0x0000000000907463 in handle_inferior_event_1
> (ecs=0x7ffd3ed92780) at
> /home/emaisin/src/binutils-gdb/gdb/infrun.c:5375
> #19 0x00000000009075aa in handle_inferior_event (ecs=0x7ffd3ed92780)
> at /home/emaisin/src/binutils-gdb/gdb/infrun.c:5410
> #20 0x000000000090449a in fetch_inferior_event (client_data=0x0) at
> /home/emaisin/src/binutils-gdb/gdb/infrun.c:3924
> #21 0x00000000008efe47 in inferior_event_handler
> (event_type=INF_REG_EVENT, client_data=0x0) at
> /home/emaisin/src/binutils-gdb/gdb/inf-loop.c:43
> #22 0x000000000090ef4b in infrun_async_inferior_event_handler
> (data=0x0) at /home/emaisin/src/binutils-gdb/gdb/infrun.c:9164
> #23 0x00000000008aaa43 in check_async_event_handlers () at
> /home/emaisin/src/binutils-gdb/gdb/event-loop.c:1064
> #24 0x00000000008a9375 in gdb_do_one_event () at
> /home/emaisin/src/binutils-gdb/gdb/event-loop.c:326
> #25 0x00000000008a9426 in start_event_loop () at
> /home/emaisin/src/binutils-gdb/gdb/event-loop.c:371
> #26 0x000000000093d38f in captured_command_loop () at
> /home/emaisin/src/binutils-gdb/gdb/main.c:330
> #27 0x000000000093e87a in captured_main (data=0x7ffd3ed929e0) at
> /home/emaisin/src/binutils-gdb/gdb/main.c:1157
> #28 0x000000000093e945 in gdb_main (args=0x7ffd3ed929e0) at
> /home/emaisin/src/binutils-gdb/gdb/main.c:1173
> #29 0x0000000000411f5c in main (argc=10, argv=0x7ffd3ed92ae8) at
> /home/emaisin/src/binutils-gdb/gdb/gdb.c:32
Ping. Since there would be multiple ways of handling this, I'd like to
get a second opinion to know if this makes sense.
Simon
More information about the Gdb-patches
mailing list