From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4785 invoked by alias); 27 Sep 2010 23:28:53 -0000 Received: (qmail 4775 invoked by uid 22791); 27 Sep 2010 23:28:50 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_JC,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 27 Sep 2010 23:28:44 +0000 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8RNShsu027779 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 27 Sep 2010 19:28:43 -0400 Received: from host1.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8RNSfb5018306 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 27 Sep 2010 19:28:42 -0400 Received: from host1.dyn.jankratochvil.net (localhost [127.0.0.1]) by host1.dyn.jankratochvil.net (8.14.4/8.14.4) with ESMTP id o8RNSe73020771 for ; Tue, 28 Sep 2010 01:28:40 +0200 Received: (from jkratoch@localhost) by host1.dyn.jankratochvil.net (8.14.4/8.14.4/Submit) id o8RNSdAm020770 for gdb-patches@sourceware.org; Tue, 28 Sep 2010 01:28:39 +0200 Date: Tue, 28 Sep 2010 15:15:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Fix printing parameters of inlined functions Message-ID: <20100927232839.GA22548@host1.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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: 2010-09/txt/msg00467.txt.bz2 Hi, GDB now prints: #0 0x00000000004004c2 in func (mainparam=) #1 main (mainparam=) at file1.txt:1 instead of: #0 0x00000000004004c2 in func (funcparam=) #1 main (mainparam=) at file1.txt:1 That is it uses parameters of the non-inlined function at that PC. No regressions on {x86_64,x86_64-m32,i686}-fedora14snapshot-linux-gnu. The new testcase has been verified on ppc64 (for the leading dot). If only minimal symbol has been found, "func ()" is only printed. Thanks, Jan gdb/ 2010-09-28 Jan Kratochvil 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-28 Jan Kratochvil 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)); @@ -791,13 +797,13 @@ print_frame (struct frame_info *frame, int print_level, annotate_frame_args (); ui_out_text (uiout, " ("); - if (print_args) + if (print_args && func != NULL) { struct print_args_args args; 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 . */ + +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 . */ + +/* 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 . + +# 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=\\)\r\n#1 main \\(mainparam=\\)\[^\r\n\]*"