This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch] Fix printing parameters of inlined functions
On Wednesday 29 September 2010 23:24:46, Jan Kratochvil wrote:
> On Tue, 28 Sep 2010 10:40:45 +0200, Pedro Alves wrote:
> > Looks good to me. One note:
> >
> > On Tuesday 28 September 2010 00:28:39, Jan Kratochvil wrote:
> > > ui_out_text (uiout, " (");
> > > - if (print_args)
> > > + if (print_args && func != NULL)
> >
> > I think this changes MI behaviour, but I didn't try it.
> > It looks like we will print no "args" list at all, while
> > before it would print an empty "args" list. No sure whether that's
> > a safe change.
>
> I can confirm for an inferior without -g it changed:
> frame={addr="0x0000000000400478",func="main",args=[]}
> ->
> frame={addr="0x0000000000400478",func="main"}
>
> While I would find it even a wised change there was a precedent MI2 should be
> kept strictly compatible. Therefore changed the code to keep the
> compatibility.
>
> The called function has been prepared for a FUNC == NULL case anyway.
>
> No regressions on {x86_64,x86_64-m32,i686}-fedora14snapshot-linux-gnu.
>
>
Okay, thanks.
--
Pedro Alves
> Thanks,
> Jan
>
>
> gdb/
> 2010-09-30 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Fix printing parameters of inlined functions.
> * ada-lang.c (is_known_support_routine)
> (ada_unhandled_exception_name_addr_from_raise): Provide NULL parameter
> for find_frame_funname.
> * python/py-frame.c (frapy_name): Likewise.
> * stack.c (find_frame_funname): New parameter funcp. Update the
> function comment. Fill it in.
> (print_frame): New variable func. Initialize it by
> find_frame_funname. Print arguments only if FUNC is not NULL. Use
> FUNC as the parameter of print_args_stub.
> * stack.h (find_frame_funname): New parameter funcp. Remove the
> function declaration comment.
>
> gdb/testsuite/
> 2010-09-30 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Fix printing parameters of inlined functions.
> * gdb.dwarf2/dw2-inline-param.exp: New file.
> * gdb.dwarf2/dw2-inline-param-main.c: New file.
> * gdb.dwarf2/dw2-inline-param.S: New file.
>
> --- a/gdb/ada-lang.c
> +++ b/gdb/ada-lang.c
> @@ -10325,7 +10325,7 @@ is_known_support_routine (struct frame_info *frame)
>
> /* Check whether the function is a GNAT-generated entity. */
>
> - find_frame_funname (frame, &func_name, &func_lang);
> + find_frame_funname (frame, &func_name, &func_lang, NULL);
> if (func_name == NULL)
> return 1;
>
> @@ -10393,7 +10393,7 @@ ada_unhandled_exception_name_addr_from_raise (void)
> char *func_name;
> enum language func_lang;
>
> - find_frame_funname (fi, &func_name, &func_lang);
> + find_frame_funname (fi, &func_name, &func_lang, NULL);
> if (func_name != NULL
> && strcmp (func_name, exception_info->catch_exception_sym) == 0)
> break; /* We found the frame we were looking for... */
> --- a/gdb/python/py-frame.c
> +++ b/gdb/python/py-frame.c
> @@ -126,7 +126,7 @@ frapy_name (PyObject *self, PyObject *args)
> {
> FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
>
> - find_frame_funname (frame, &name, &lang);
> + find_frame_funname (frame, &name, &lang, NULL);
> }
> GDB_PY_HANDLE_EXCEPTION (except);
>
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -661,16 +661,19 @@ print_frame_info (struct frame_info *frame, int print_level,
> gdb_flush (gdb_stdout);
> }
>
> -/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding
> - to FRAME. */
> +/* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
> + corresponding to FRAME. */
> +
> void
> find_frame_funname (struct frame_info *frame, char **funname,
> - enum language *funlang)
> + enum language *funlang, struct symbol **funcp)
> {
> struct symbol *func;
>
> *funname = NULL;
> *funlang = language_unknown;
> + if (funcp)
> + *funcp = NULL;
>
> func = get_frame_function (frame);
> if (func)
> @@ -715,6 +718,8 @@ find_frame_funname (struct frame_info *frame, char **funname,
> {
> *funname = SYMBOL_PRINT_NAME (func);
> *funlang = SYMBOL_LANGUAGE (func);
> + if (funcp)
> + *funcp = func;
> if (*funlang == language_cplus)
> {
> /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
> @@ -756,11 +761,12 @@ print_frame (struct frame_info *frame, int print_level,
> struct ui_stream *stb;
> struct cleanup *old_chain, *list_chain;
> struct value_print_options opts;
> + struct symbol *func;
>
> stb = ui_out_stream_new (uiout);
> old_chain = make_cleanup_ui_out_stream_delete (stb);
>
> - find_frame_funname (frame, &funname, &funlang);
> + find_frame_funname (frame, &funname, &funlang, &func);
>
> annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
> gdbarch, get_frame_pc (frame));
> @@ -797,7 +803,7 @@ print_frame (struct frame_info *frame, int print_level,
> struct cleanup *args_list_chain;
>
> args.frame = frame;
> - args.func = find_pc_function (get_frame_address_in_block (frame));
> + args.func = func;
> args.stream = gdb_stdout;
> args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args");
> catch_errors (print_args_stub, &args, "", RETURN_MASK_ERROR);
> --- a/gdb/stack.h
> +++ b/gdb/stack.h
> @@ -22,10 +22,8 @@
>
> void select_frame_command (char *level_exp, int from_tty);
>
> -/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding
> - to FRAME. */
> void find_frame_funname (struct frame_info *frame, char **funname,
> - enum language *funlang);
> + enum language *funlang, struct symbol **funcp);
>
> typedef void (*iterate_over_block_arg_local_vars_cb) (const char *symbol_print_name,
> struct symbol *sym,
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-param-main.c
> @@ -0,0 +1,42 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2010 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +asm (".globl cu_text_start");
> +asm ("cu_text_start:");
> +
> +volatile int v;
> +
> +int
> +main (void)
> +{
> + asm (".globl block_start");
> + asm ("block_start:");
> +
> + v = 1;
> +
> + asm ("break_at:");
> +
> + v = 2;
> +
> + asm (".globl block_end");
> + asm ("block_end:");
> +
> + return 0;
> +}
> +
> +asm (".globl cu_text_end");
> +asm ("cu_text_end:");
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-param.S
> @@ -0,0 +1,152 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2010 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +/* Debug information */
> +
> + .section .debug_info
> +.Lcu1_begin:
> + /* CU header */
> + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
> +.Lcu1_start:
> + .2byte 2 /* DWARF Version */
> + .4byte .Labbrev1_begin /* Offset into abbrev section */
> + .byte 4 /* Pointer size */
> +
> + /* CU die */
> + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
> + .4byte cu_text_start /* DW_AT_low_pc */
> + .4byte cu_text_end /* DW_AT_high_pc */
> + .ascii "file1.txt\0" /* DW_AT_name */
> + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */
> + .byte 1 /* DW_AT_language (C) */
> +
> +.Ltype_int:
> + .uleb128 3 /* Abbrev: DW_TAG_base_type */
> + .ascii "int\0" /* DW_AT_name */
> + .byte 4 /* DW_AT_byte_size */
> + .byte 5 /* DW_AT_encoding */
> +
> + .uleb128 4 /* Abbrev: DW_TAG_subprogram */
> + .ascii "main\0" /* DW_AT_name */
> + .4byte cu_text_start /* DW_AT_low_pc */
> + .4byte cu_text_end /* DW_AT_high_pc */
> + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
> + .byte 1 /* DW_AT_external */
> + .byte 1 /* DW_AT_prototyped */
> +
> + .uleb128 6 /* Abbrev: DW_TAG_formal_parameter */
> + .ascii "mainparam\0" /* DW_AT_name */
> +
> + .uleb128 5 /* Abbrev: DW_TAG_inlined_subroutine */
> + .ascii "func\0" /* DW_AT_name */
> + .4byte block_start /* DW_AT_low_pc */
> + .4byte block_end /* DW_AT_high_pc */
> + .byte 3 /* DW_AT_inline (DW_INL_declared_inlined) */
> + .byte 1 /* DW_AT_prototyped */
> + .byte 0 /* DW_AT_call_file */
> + .byte 1 /* DW_AT_call_line */
> +
> + .uleb128 6 /* Abbrev: DW_TAG_formal_parameter */
> + .ascii "funcparam\0" /* DW_AT_name */
> +
> + .byte 0 /* End of children of func */
> +
> + .byte 0 /* End of children of main */
> +
> + .byte 0 /* End of children of CU */
> +
> +.Lcu1_end:
> +
> +/* Abbrev table */
> + .section .debug_abbrev
> +.Labbrev1_begin:
> + .uleb128 1 /* Abbrev code */
> + .uleb128 0x11 /* DW_TAG_compile_unit */
> + .byte 1 /* has_children */
> + .uleb128 0x11 /* DW_AT_low_pc */
> + .uleb128 0x1 /* DW_FORM_addr */
> + .uleb128 0x12 /* DW_AT_high_pc */
> + .uleb128 0x1 /* DW_FORM_addr */
> + .uleb128 0x3 /* DW_AT_name */
> + .uleb128 0x8 /* DW_FORM_string */
> + .uleb128 0x25 /* DW_AT_producer */
> + .uleb128 0x8 /* DW_FORM_string */
> + .uleb128 0x13 /* DW_AT_language */
> + .uleb128 0xb /* DW_FORM_data1 */
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> +
> + .uleb128 3 /* Abbrev code */
> + .uleb128 0x24 /* DW_TAG_base_type */
> + .byte 0 /* has_children */
> + .uleb128 0x3 /* DW_AT_name */
> + .uleb128 0x8 /* DW_FORM_string */
> + .uleb128 0xb /* DW_AT_byte_size */
> + .uleb128 0xb /* DW_FORM_data1 */
> + .uleb128 0x3e /* DW_AT_encoding */
> + .uleb128 0xb /* DW_FORM_data1 */
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> +
> + .uleb128 4 /* Abbrev code */
> + .uleb128 0x2e /* DW_TAG_subprogram */
> + .byte 1 /* has_children */
> + .uleb128 0x3 /* DW_AT_name */
> + .uleb128 0x8 /* DW_FORM_string */
> + .uleb128 0x11 /* DW_AT_low_pc */
> + .uleb128 0x1 /* DW_FORM_addr */
> + .uleb128 0x12 /* DW_AT_high_pc */
> + .uleb128 0x1 /* DW_FORM_addr */
> + .uleb128 0x49 /* DW_AT_type */
> + .uleb128 0x13 /* DW_FORM_ref4 */
> + .uleb128 0x3f /* DW_AT_external */
> + .uleb128 0xc /* DW_FORM_flag */
> + .uleb128 0x27 /* DW_AT_prototyped */
> + .uleb128 0xc /* DW_FORM_flag */
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> +
> + .uleb128 5 /* Abbrev code */
> + .uleb128 0x1d /* DW_TAG_inlined_subroutine */
> + .byte 1 /* has_children */
> + .uleb128 0x3 /* DW_AT_name */
> + .uleb128 0x8 /* DW_FORM_string */
> + .uleb128 0x11 /* DW_AT_low_pc */
> + .uleb128 0x1 /* DW_FORM_addr */
> + .uleb128 0x12 /* DW_AT_high_pc */
> + .uleb128 0x1 /* DW_FORM_addr */
> + .uleb128 0x20 /* DW_AT_inline */
> + .uleb128 0xb /* DW_FORM_data1 */
> + .uleb128 0x27 /* DW_AT_prototyped */
> + .uleb128 0xc /* DW_FORM_flag */
> + .uleb128 0x58 /* DW_AT_call_file */
> + .uleb128 0xb /* DW_FORM_data1 */
> + .uleb128 0x59 /* DW_AT_call_line */
> + .uleb128 0xb /* DW_FORM_data1 */
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> +
> + .uleb128 6 /* Abbrev code */
> + .uleb128 0x05 /* DW_TAG_formal_parameter */
> + .byte 0 /* has_children */
> + .uleb128 0x3 /* DW_AT_name */
> + .uleb128 0x8 /* DW_FORM_string */
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> +
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-param.exp
> @@ -0,0 +1,65 @@
> +# Copyright 2010 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# This test can only be run on targets which support DWARF-2 and use gas.
> +# For now pick a sampling of likely targets.
> +if {![istarget *-*-linux*]
> + && ![istarget *-*-gnu*]
> + && ![istarget *-*-elf*]
> + && ![istarget *-*-openbsd*]
> + && ![istarget arm-*-eabi*]
> + && ![istarget powerpc-*-eabi*]} {
> + return 0
> +}
> +
> +set testfile dw2-inline-param
> +set binfile ${objdir}/${subdir}/${testfile}
> +if { [build_executable ${testfile}.exp "${testfile}" [list ${testfile}-main.c ${testfile}.S] {nodebug}] } {
> + return -1
> +}
> +
> +clean_restart ${testfile}
> +
> +set break_at ""
> +set test "info addr break_at"
> +gdb_test_multiple $test $test {
> + -re "Symbol \"break_at\" is at (0x\[0-9a-f\]+) in .*\r\n$gdb_prompt $" {
> + set break_at $expect_out(1,string)
> + pass $test
> + }
> +}
> +
> +gdb_unload
> +
> +# Strip out any labels there as they could corrupt the `main' name.
> +
> +set objcopy_program [transform objcopy]
> +set result [catch "exec $objcopy_program -N block_start -N block_end -N break_at ${binfile}" output]
> +verbose "result is $result"
> +verbose "output is $output"
> +if {$result != 0} {
> + return -1
> +}
> +
> +gdb_load ${binfile}
> +if [target_info exists gdb_stub] {
> + gdb_step_for_stub;
> +}
> +
> +if ![runto "*${break_at}"] {
> + return -1
> +}
> +
> +gdb_test "bt" "#0 (0x\[0-9a-f\]+ in )?func \\(funcparam=<value optimized out>\\)\r\n#1 main \\(mainparam=<value optimized out>\\)\[^\r\n\]*"
>