From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1134 invoked by alias); 8 Nov 2007 01:19:50 -0000 Received: (qmail 1114 invoked by uid 22791); 8 Nov 2007 01:19:48 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 08 Nov 2007 01:19:45 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id B2EBD2AC322 for ; Wed, 7 Nov 2007 20:19:43 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id X0ub7drtG+8r for ; Wed, 7 Nov 2007 20:19:43 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 238792AC31D for ; Wed, 7 Nov 2007 20:19:43 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id A32E1E7ACA; Wed, 7 Nov 2007 20:19:40 -0500 (EST) Date: Thu, 08 Nov 2007 01:19:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [RFC] new setting to not-print frame arguments values Message-ID: <20071108011940.GI3911@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="8X7/QrJGcKSMr1RN" Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-11/txt/msg00151.txt.bz2 --8X7/QrJGcKSMr1RN Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 3278 Hello, Context: -------- As a user, I had often wished that there would be a way to print backtraces without printing any argument, almost like the way we print a frame for a function that does not have any debug info. This is because the argument values tend to clutter the part of the backtrace that I am really interested in. But recently, a bug that we fixed causing arguments to be printed correctly instead of not printed at all, had the unexpected side-effect of dramatically slowing down the printing of each frame in a backtrace. The slow-down is due to the encoding used for Ada, which requires what we call "parallel lookups", which are lookups that scan through the entire application. This is because we are forced by non-dwarf debugging info (stabs) to use parallel types to help us determine certain characteristics that can not be encoded otherwise. This is hardly noticeable on small projects, but quite annoying on large scale projects. These lookups are only used for non-scalar types, such as records and arrays. So, since we cannot do without the parallel lookups for now, the following idea emerged. Proposal: --------- We would like to propose the inclusion of a new setting: (gdb) set print frame-arguments (all|scalars|none) The effect would be: (a) set print frame-arguments all print all argument values. Same behavior as before. (b) set print frame-arguments scalars print the argument value only if the argument is a scalar. (c) set print frame-arguments none Print no argument value at all. When the argument value is not printed, its value is substituted with "..." to give the user a clue that the value has intentionally not been printed. For our needs, AdaCore will set the default "print frame-arguments" to "scalars", but we may here want to preserve the default behavior, and thus use "all" by default. This is what this patch implements. Testcase and documentation are still missing, but will be provided later if the idea is accepted. The testcase will be in C, but for now, with Ada, here is the output we get for each value of this new switch: (gdb) set print frame-arguments all (gdb) frame #1 0x0804954f in pck.call_me (int=1, flt=2.0, bln=true, chr=106 'j', sad=(system.address) 0xbfac2ae4, rec=(a => 3, b => 7)) at pck.adb:17 17 Break_Me; (gdb) set print frame-arguments scalars (gdb) frame #1 0x0804954f in pck.call_me (int=1, flt=2.0, bln=true, chr=106 'j', sad=(system.address) 0xbfac2ae4, rec=...) at pck.adb:17 17 Break_Me; (gdb) set print frame-arguments none (gdb) frame #1 0x0804954f in pck.call_me (int=..., flt=..., bln=..., chr=..., sad=..., rec=...) at pck.adb:17 17 Break_Me; 2007-11-06 Joel Brobecker * stack.c (print_frame_arguments_choices): New static global. (print_frame_arguments): Likewise. (print_this_frame_argument_p): New function. (print_frame_args): Print the argument value only when appropriate. (_initialize_task): Add new "set/show print frame-arguments" command. Tested on x86-linux. No regression. Any comments? Let's be bold: Ok to checkin? ;-) Thanks, -- Joel --8X7/QrJGcKSMr1RN Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="stack.c.diff" Content-length: 4185 Index: stack.c =================================================================== RCS file: /cvs/src/src/gdb/stack.c,v retrieving revision 1.156 diff -u -p -r1.156 stack.c --- stack.c 2 Nov 2007 14:47:28 -0000 1.156 +++ stack.c 8 Nov 2007 01:00:11 -0000 @@ -50,6 +50,13 @@ void (*deprecated_selected_frame_level_changed_hook) (int); +/* The possible choices of "set print frame-arguments, and the value + of this setting. */ + +static const char *print_frame_arguments_choices[] = + {"all", "scalars", "none", NULL}; +static const char *print_frame_arguments = "all"; + /* Prototypes for local functions. */ static void print_frame_local_vars (struct frame_info *, int, @@ -148,6 +155,44 @@ print_frame_nameless_args (struct frame_ } } +/* Return non-zero if the debugger should print the value of the provided + symbol parameter (SYM). */ + +static int +print_this_frame_argument_p (struct symbol *sym) +{ + struct type *type; + + /* If the user asked to print no argument at all, then obviously + do not print this argument. */ + + if (strcmp (print_frame_arguments, "none") == 0) + return 0; + + /* If the user asked to print all arguments, then we should print + that one. */ + + if (strcmp (print_frame_arguments, "all") == 0) + return 1; + + /* The user asked to print only the scalar arguments, so do not + print the non-scalar ones. */ + + type = CHECK_TYPEDEF (SYMBOL_TYPE (sym)); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_SET: + case TYPE_CODE_STRING: + case TYPE_CODE_BITSTRING: + return 0; + default: + return 1; + } +} + /* Print the arguments of frame FRAME on STREAM, given the function FUNC running in that frame (as a symbol), where NUM is the number of arguments according to the stack frame (or -1 if the number of @@ -304,23 +349,30 @@ print_frame_args (struct symbol *func, s annotate_arg_name_end (); ui_out_text (uiout, "="); - /* Avoid value_print because it will deref ref parameters. - We just want to print their addresses. Print ??? for - args whose address we do not know. We pass 2 as - "recurse" to val_print because our standard indentation - here is 4 spaces, and val_print indents 2 for each - recurse. */ - val = read_var_value (sym, frame); - - annotate_arg_value (val == NULL ? NULL : value_type (val)); + if (print_this_frame_argument_p (sym)) + { + /* Avoid value_print because it will deref ref parameters. + We just want to print their addresses. Print ??? for + args whose address we do not know. We pass 2 as + "recurse" to val_print because our standard indentation + here is 4 spaces, and val_print indents 2 for each + recurse. */ + val = read_var_value (sym, frame); + + annotate_arg_value (val == NULL ? NULL : value_type (val)); + + if (val) + { + common_val_print (val, stb->stream, 0, 0, 2, + Val_no_prettyprint); + ui_out_field_stream (uiout, "value", stb); + } + else + ui_out_text (uiout, "???"); + } + else + ui_out_text (uiout, "..."); - if (val) - { - common_val_print (val, stb->stream, 0, 0, 2, Val_no_prettyprint); - ui_out_field_stream (uiout, "value", stb); - } - else - ui_out_text (uiout, "???"); /* Invoke ui_out_tuple_end. */ do_cleanups (list_chain); @@ -2039,6 +2091,12 @@ Usage: func \n")); add_info ("catch", catch_info, _("Exceptions that can be caught in the current stack frame.")); + add_setshow_enum_cmd ("frame-arguments", class_stack, + print_frame_arguments_choices, &print_frame_arguments, + _("Set printing of non-scalar frame arguments"), + _("Show printing of non-scalar frame arguments"), + NULL, NULL, NULL, &setprintlist, &showprintlist); + #if 0 add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, _(\ "Specify maximum number of frames for \"backtrace\" to print by default."), --8X7/QrJGcKSMr1RN--