From patchwork Sat May 4 21:55:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philippe Waroquiers X-Patchwork-Id: 32557 Received: (qmail 75530 invoked by alias); 4 May 2019 21:57:44 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 75477 invoked by uid 89); 4 May 2019 21:57:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.1 spammy=essential, internal_error, End, sym X-HELO: mailsec111.isp.belgacom.be Received: from mailsec111.isp.belgacom.be (HELO mailsec111.isp.belgacom.be) (195.238.20.107) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 04 May 2019 21:57:42 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skynet.be; i=@skynet.be; q=dns/txt; s=securemail; t=1557007061; x=1588543061; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+P3psCwgz6uVAniMvm08XX10qPXvih/ivFxW6aMDmpw=; b=St0AgA9urueJMPRxyd8hjyNG6HbK2VGywjeZNLdw4H8PSp4uKVnZW7+W 6lM/CJDnZBcFVXyF1mkLRYM4jemcXw==; Received: from 59.151-129-109.adsl-dyn.isp.belgacom.be (HELO md.home) ([109.129.151.59]) by relay.skynet.be with ESMTP/TLS/DHE-RSA-AES128-GCM-SHA256; 04 May 2019 23:55:50 +0200 From: Philippe Waroquiers To: gdb-patches@sourceware.org Cc: Philippe Waroquiers Subject: [RFA 1/3] Implement 'set print frame-info|frame-arguments presence'. Date: Sat, 4 May 2019 23:55:36 +0200 Message-Id: <20190504215538.29821-2-philippe.waroquiers@skynet.be> In-Reply-To: <20190504215538.29821-1-philippe.waroquiers@skynet.be> References: <20190504215538.29821-1-philippe.waroquiers@skynet.be> MIME-Version: 1.0 X-IsSubscribed: yes New settings allow to better control what frame information is printed. 'set print frame-info' allows to override the default frame information printed when a GDB command prints a frame. It is now possible to have very short frame information by using the new 'set print frame-arguments presence' and 'set print frame-info short_loc'. Combined with 'set print address off', a backtrace will only show the essential information to see the function call chain, e.g.: (gdb) set print address off (gdb) set print frame-arguments presence (gdb) set print frame-info short_loc (gdb) bt #0 break_me () #1 call_me (...) #2 main () (gdb) This is handy in particular for big backtraces with functions having many arguments. --- gdb/ChangeLog | 14 +++++++++ gdb/frame.h | 28 +++++++++++------ gdb/stack.c | 86 ++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 104 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 09a4a0af5a..dd214b47fa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -6297,3 +6297,17 @@ version-control: never coding: utf-8 End: +2019-05-04 Philippe Waroquiers + + * NEWS: Mention 'set|show print frame-info'. Mention new + 'presence' value for 'frame-arguments'. + * frame.h (enum print_what): New value 'SHORT_LOCATION', update + comments. + * stack.c (print_frame_arguments_choices): New value 'presence'. + (print_frame_args): Only print dots for args if print frame-arguments + is 'presence'. + (print_what_frame_info_string, print_what_frame_info) + (set_print_frame_info_command): New variables and function. + (print_frame_info): Update comment. Use print_what_frame_info + to decide what to print. + (_initialize_stack): Call add_setshow_enum_cmd for frame-info. diff --git a/gdb/frame.h b/gdb/frame.h index 0a0baf46a0..4c0ee4d53e 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -675,18 +675,28 @@ extern struct gdbarch *frame_unwind_arch (frame_info *next_frame); extern struct gdbarch *frame_unwind_caller_arch (struct frame_info *frame); -/* Values for the source flag to be used in print_frame_info_base(). */ +/* Values for the source flag to be used in print_frame_info (). + For all the cases below, the address is never printed if + 'set print address' is off. When 'set print address' is on, + the address is printed if the program counter is not at the + beginning of the source line of the frame + and PRINT_WHAT is != LOC_AND_ADDRESS. */ enum print_what - { - /* Print only the source line, like in stepi. */ - SRC_LINE = -1, - /* Print only the location, i.e. level, address (sometimes) - function, args, file, line, line num. */ + { + /* Print only the address, source line, like in stepi. */ + SRC_LINE = -1, + /* Print only the location, i.e. level, address, + function, args (as controlled by 'set print frame-arguments'), + file, line, line num. */ LOCATION, /* Print both of the above. */ - SRC_AND_LOC, - /* Print location only, but always include the address. */ - LOC_AND_ADDRESS + SRC_AND_LOC, + /* Print location only, print the address even if the program counter + is at the beginning of the source line. */ + LOC_AND_ADDRESS, + /* Print only level and function, + i.e. location only, without address, file, line, line num. */ + SHORT_LOCATION }; /* Allocate zero initialized memory from the frame cache obstack. diff --git a/gdb/stack.c b/gdb/stack.c index e5de10949d..495642a83b 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -57,7 +57,7 @@ of this setting. */ static const char *const print_frame_arguments_choices[] = - {"all", "scalars", "none", NULL}; + {"all", "scalars", "none", "presence", NULL}; static const char *print_frame_arguments = "scalars"; /* If non-zero, don't invoke pretty-printers for frame arguments. */ @@ -539,8 +539,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame, long highest_offset = -1; /* Number of ints of arguments that we have printed so far. */ int args_printed = 0; + /* True if we should print arg names. If false, we only indicate + the presence of arguments by printing ellipsis. */ + int print_names = strcmp (print_frame_arguments, "presence"); /* True if we should print arguments, false otherwise. */ - int print_args = strcmp (print_frame_arguments, "none"); + int print_args = print_names && strcmp (print_frame_arguments, "none"); if (func) { @@ -560,6 +563,13 @@ print_frame_args (struct symbol *func, struct frame_info *frame, if (!SYMBOL_IS_ARGUMENT (sym)) continue; + if (!print_names) + { + uiout->text ("..."); + first = 0; + break; + } + switch (SYMBOL_CLASS (sym)) { case LOC_ARG: @@ -708,8 +718,11 @@ print_frame_args (struct symbol *func, struct frame_info *frame, else start = highest_offset; - print_frame_nameless_args (frame, start, num - args_printed, - first, stream); + if (!print_names && !first && num > 0) + uiout->text ("..."); + else + print_frame_nameless_args (frame, start, num - args_printed, + first, stream); } } @@ -766,13 +779,42 @@ do_gdb_disassembly (struct gdbarch *gdbarch, } } +/* The possible choices of "set print frame-info", and the value + of this setting. */ + +static const char *const print_frame_info_choices[] = + {"src_line", "location", "src_and_loc", "loc_and_address", "short_loc", + "auto", NULL}; +static const char *print_what_frame_info_string = "auto"; +static gdb::optional print_what_frame_info; + +/* Set command. Change the current frame info to print. */ + +static void +set_print_frame_info_command (const char *ignore, + int from_tty, struct cmd_list_element *c) +{ + if (strcmp (print_what_frame_info_string, "src_line") == 0) + print_what_frame_info = SRC_LINE; + else if (strcmp (print_what_frame_info_string, "location") == 0) + print_what_frame_info = LOCATION; + else if (strcmp (print_what_frame_info_string, "src_and_loc") == 0) + print_what_frame_info = SRC_AND_LOC; + else if (strcmp (print_what_frame_info_string, "loc_and_address") == 0) + print_what_frame_info = LOC_AND_ADDRESS; + else if (strcmp (print_what_frame_info_string, "short_loc") == 0) + print_what_frame_info = SHORT_LOCATION; + else if (strcmp (print_what_frame_info_string, "auto") == 0) + print_what_frame_info.reset (); + else + internal_error (__FILE__, __LINE__, + "Unexpected set print frame-info `%s'.", + print_what_frame_info_string); +} + /* Print information about frame FRAME. The output is format according - to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS. The meaning of - PRINT_WHAT is: - - SRC_LINE: Print only source line. - LOCATION: Print only location. - SRC_AND_LOC: Print location and source line. + to PRINT_LEVEL and PRINT_WHAT and PRINT_ARGS. For the meaning of + PRINT_WHAT, see enum print_what comments in frame.h. Used in "where" output, and to emit breakpoint or step messages. */ @@ -787,6 +829,12 @@ print_frame_info (struct frame_info *frame, int print_level, int location_print; struct ui_out *uiout = current_uiout; + if (!current_uiout->is_mi_like_p () && print_what_frame_info.has_value ()) + { + /* Use the specific frame information desired by the user. */ + print_what = *print_what_frame_info; + } + if (get_frame_type (frame) == DUMMY_FRAME || get_frame_type (frame) == SIGTRAMP_FRAME || get_frame_type (frame) == ARCH_FRAME) @@ -850,10 +898,10 @@ print_frame_info (struct frame_info *frame, int print_level, to get the line containing FRAME->pc. */ symtab_and_line sal = find_frame_sal (frame); - location_print = (print_what == LOCATION + location_print = (print_what == LOCATION + || print_what == SRC_AND_LOC || print_what == LOC_AND_ADDRESS - || print_what == SRC_AND_LOC); - + || print_what == SHORT_LOCATION); if (location_print || !sal.symtab) print_frame (frame, print_level, print_what, print_args, sal); @@ -1210,7 +1258,7 @@ print_frame (struct frame_info *frame, int print_level, QUIT; } uiout->text (")"); - if (sal.symtab) + if (print_what != SHORT_LOCATION && sal.symtab) { const char *filename_display; @@ -1233,7 +1281,8 @@ print_frame (struct frame_info *frame, int print_level, annotate_frame_source_end (); } - if (pc_p && (funname == NULL || sal.symtab == NULL)) + if (print_what != SHORT_LOCATION + && pc_p && (funname == NULL || sal.symtab == NULL)) { char *lib = solib_name_from_address (get_frame_program_space (frame), get_frame_pc (frame)); @@ -3106,6 +3155,13 @@ Usage: func NAME")); _("Show printing of non-scalar frame arguments"), NULL, NULL, NULL, &setprintlist, &showprintlist); + add_setshow_enum_cmd ("frame-info", class_stack, + print_frame_info_choices, &print_what_frame_info_string, + _("Set printing of frame information"), + _("Show printing of frame information"), + NULL, set_print_frame_info_command, NULL, + &setprintlist, &showprintlist); + add_setshow_boolean_cmd ("frame-arguments", no_class, &print_raw_frame_arguments, _("\ Set whether to print frame arguments in raw form."), _("\