RFC: fix PR c++/14999

Tom Tromey tromey@redhat.com
Tue Jan 8 17:11:00 GMT 2013


This fixes PR c++/14999.

The problem here is that setting a tracepoint and collecting a certain
local variable will cause a crash, if the source code was compiled with
clang.

The bug is just a missing call to require_rvalue when handling
DW_OP_fbreg in the DWARF->AX translator.

This patch includes a test case which is assembly created by clang, then
lightly hacked by me (to change the file and directory names).  I think
this is ok, since the original source file is so small; but if you
disagree let me know.

Built and regtested on x86-64 Fedora 16.

Tom

    	PR c++/14999:
    	* dwarf2loc.c (dwarf2_compile_expr_to_ax) <DW_OP_fbreg>:
    	Call require_rvalue.
    
    	* gdb.dwarf2/trace-crash.s: New file.
    	* gdb.dwarf2/trace-crash.exp: New file.

diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 33300ee..2282feb 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2878,6 +2878,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 	    dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart,
 				       datastart + datalen, per_cu);
+	    require_rvalue (expr, loc);
 
 	    if (offset != 0)
 	      {
diff --git a/gdb/testsuite/gdb.dwarf2/trace-crash.S b/gdb/testsuite/gdb.dwarf2/trace-crash.S
new file mode 100644
index 0000000..3a9a771
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/trace-crash.S
@@ -0,0 +1,295 @@
+/* This file was created using Clang -g -S from this source
+   code:
+
+   int func(int p) {
+    int x = p + 3;
+    return x;
+   }
+
+   int main() { return func(3); }
+
+   See http://sourceware.org/bugzilla/show_bug.cgi?id=14999
+*/
+
+	.file	"trace-crash.c"
+	.file	1 "trace-crash.c"
+	.text
+	.globl	func
+	.align	16, 0x90
+	.type	func,@function
+func:                                   # @func
+	.cfi_startproc
+.Lfunc_begin0:
+	.loc	1 1 0                   # trace-crash.c:1:0
+# BB#0:                                 # %entry
+	movl	%edi, -4(%rsp)
+	.loc	1 2 0 prologue_end      # trace-crash.c:2:0
+.Ltmp0:
+	movl	-4(%rsp), %edi
+	addl	$3, %edi
+	movl	%edi, -8(%rsp)
+	.loc	1 3 0                   # trace-crash.c:3:0
+	movl	-8(%rsp), %eax
+	ret
+.Ltmp1:
+.Ltmp2:
+	.size	func, .Ltmp2-func
+.Lfunc_end0:
+	.cfi_endproc
+
+	.globl	main
+	.align	16, 0x90
+	.type	main,@function
+main:                                   # @main
+	.cfi_startproc
+.Lfunc_begin1:
+	.loc	1 6 0                   # trace-crash.c:6:0
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp5:
+	.cfi_def_cfa_offset 16
+.Ltmp6:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp7:
+	.cfi_def_cfa_register %rbp
+	subq	$16, %rsp
+	movl	$3, %edi
+	movl	$0, -4(%rbp)
+	.loc	1 6 0 prologue_end      # trace-crash.c:6:0
+.Ltmp8:
+	callq	func
+	addq	$16, %rsp
+	popq	%rbp
+	ret
+.Ltmp9:
+.Ltmp10:
+	.size	main, .Ltmp10-main
+.Lfunc_end1:
+	.cfi_endproc
+
+.Ltext_end:
+	.data
+.Ldata_end:
+	.text
+.Lsection_end1:
+	.section	.debug_info,"",@progbits
+.Lsection_info:
+	.section	.debug_abbrev,"",@progbits
+.Lsection_abbrev:
+	.section	.debug_aranges,"",@progbits
+	.section	.debug_macinfo,"",@progbits
+	.section	.debug_line,"",@progbits
+.Lsection_line:
+	.section	.debug_loc,"",@progbits
+	.section	.debug_pubtypes,"",@progbits
+	.section	.debug_str,"MS",@progbits,1
+.Linfo_string:
+	.section	.debug_ranges,"",@progbits
+.Ldebug_range:
+	.section	.debug_loc,"",@progbits
+.Lsection_debug_loc:
+	.text
+.Ltext_begin:
+	.data
+	.section	.debug_info,"",@progbits
+.L.debug_info_begin0:
+	.long	147                     # Length of Compilation Unit Info
+	.short	2                       # DWARF version number
+	.long	.L.debug_abbrev_begin   # Offset Into Abbrev. Section
+	.byte	8                       # Address Size (in bytes)
+	.byte	1                       # Abbrev [1] 0xb:0x8c DW_TAG_compile_unit
+	.long	.Linfo_string0          # DW_AT_producer
+	.short	12                      # DW_AT_language
+	.long	.Linfo_string1          # DW_AT_name
+	.quad	0                       # DW_AT_low_pc
+	.long	.Lsection_line          # DW_AT_stmt_list
+	.long	.Linfo_string2          # DW_AT_comp_dir
+	.byte	2                       # Abbrev [2] 0x26:0x4c DW_TAG_subprogram
+	.long	.Linfo_string3          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	1                       # DW_AT_decl_line
+                                        # DW_AT_prototyped
+	.long	114                     # DW_AT_type
+                                        # DW_AT_external
+	.quad	.Lfunc_begin0           # DW_AT_low_pc
+	.quad	.Lfunc_end0             # DW_AT_high_pc
+	.byte	1                       # DW_AT_frame_base
+	.byte	87
+                                        # DW_AT_APPLE_omit_frame_ptr
+	.byte	3                       # Abbrev [3] 0x43:0xe DW_TAG_formal_parameter
+	.long	.Linfo_string6          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	1                       # DW_AT_decl_line
+	.long	114                     # DW_AT_type
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	124
+	.byte	4                       # Abbrev [4] 0x51:0x20 DW_TAG_lexical_block
+	.quad	.Ltmp0                  # DW_AT_low_pc
+	.quad	.Ltmp1                  # DW_AT_high_pc
+	.byte	5                       # Abbrev [5] 0x62:0xe DW_TAG_variable
+	.long	.Linfo_string7          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	2                       # DW_AT_decl_line
+	.long	114                     # DW_AT_type
+	.byte	2                       # DW_AT_location
+	.byte	145
+	.byte	120
+	.byte	0                       # End Of Children Mark
+	.byte	0                       # End Of Children Mark
+	.byte	6                       # Abbrev [6] 0x72:0x7 DW_TAG_base_type
+	.long	.Linfo_string4          # DW_AT_name
+	.byte	5                       # DW_AT_encoding
+	.byte	4                       # DW_AT_byte_size
+	.byte	7                       # Abbrev [7] 0x79:0x1d DW_TAG_subprogram
+	.long	.Linfo_string5          # DW_AT_name
+	.byte	1                       # DW_AT_decl_file
+	.byte	6                       # DW_AT_decl_line
+	.long	114                     # DW_AT_type
+                                        # DW_AT_external
+	.quad	.Lfunc_begin1           # DW_AT_low_pc
+	.quad	.Lfunc_end1             # DW_AT_high_pc
+	.byte	1                       # DW_AT_frame_base
+	.byte	86
+	.byte	0                       # End Of Children Mark
+.L.debug_info_end0:
+	.section	.debug_abbrev,"",@progbits
+.L.debug_abbrev_begin:
+	.byte	1                       # Abbreviation Code
+	.byte	17                      # DW_TAG_compile_unit
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	37                      # DW_AT_producer
+	.byte	14                      # DW_FORM_strp
+	.byte	19                      # DW_AT_language
+	.byte	5                       # DW_FORM_data2
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	16                      # DW_AT_stmt_list
+	.byte	6                       # DW_FORM_data4
+	.byte	27                      # DW_AT_comp_dir
+	.byte	14                      # DW_FORM_strp
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	2                       # Abbreviation Code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	39                      # DW_AT_prototyped
+	.byte	25                      # DW_FORM_flag_present
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	63                      # DW_AT_external
+	.byte	25                      # DW_FORM_flag_present
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	18                      # DW_AT_high_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	64                      # DW_AT_frame_base
+	.byte	10                      # DW_FORM_block1
+	.ascii	 "\347\177"             # DW_AT_APPLE_omit_frame_ptr
+	.byte	25                      # DW_FORM_flag_present
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	3                       # Abbreviation Code
+	.byte	5                       # DW_TAG_formal_parameter
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	2                       # DW_AT_location
+	.byte	10                      # DW_FORM_block1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	4                       # Abbreviation Code
+	.byte	11                      # DW_TAG_lexical_block
+	.byte	1                       # DW_CHILDREN_yes
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	18                      # DW_AT_high_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	5                       # Abbreviation Code
+	.byte	52                      # DW_TAG_variable
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	2                       # DW_AT_location
+	.byte	10                      # DW_FORM_block1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	6                       # Abbreviation Code
+	.byte	36                      # DW_TAG_base_type
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	62                      # DW_AT_encoding
+	.byte	11                      # DW_FORM_data1
+	.byte	11                      # DW_AT_byte_size
+	.byte	11                      # DW_FORM_data1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	7                       # Abbreviation Code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	58                      # DW_AT_decl_file
+	.byte	11                      # DW_FORM_data1
+	.byte	59                      # DW_AT_decl_line
+	.byte	11                      # DW_FORM_data1
+	.byte	73                      # DW_AT_type
+	.byte	19                      # DW_FORM_ref4
+	.byte	63                      # DW_AT_external
+	.byte	25                      # DW_FORM_flag_present
+	.byte	17                      # DW_AT_low_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	18                      # DW_AT_high_pc
+	.byte	1                       # DW_FORM_addr
+	.byte	64                      # DW_AT_frame_base
+	.byte	10                      # DW_FORM_block1
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+.L.debug_abbrev_end:
+	.section	.debug_aranges,"",@progbits
+	.section	.debug_ranges,"",@progbits
+	.section	.debug_macinfo,"",@progbits
+	.section	.debug_str,"MS",@progbits,1
+.Linfo_string0:
+	.asciz	 "clang version 3.3 "
+.Linfo_string1:
+	.asciz	 "trace-crash.c"
+.Linfo_string2:
+	.asciz	 "/tmp"
+.Linfo_string3:
+	.asciz	 "func"
+.Linfo_string4:
+	.asciz	 "int"
+.Linfo_string5:
+	.asciz	 "main"
+.Linfo_string6:
+	.asciz	 "p"
+.Linfo_string7:
+	.asciz	 "x"
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/trace-crash.exp b/gdb/testsuite/gdb.dwarf2/trace-crash.exp
new file mode 100644
index 0000000..7331868
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/trace-crash.exp
@@ -0,0 +1,41 @@
+# Copyright 2013 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/>.
+
+load_lib dwarf.exp
+load_lib trace-support.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0  
+}
+
+# This test can only be run on x86-64 targets.
+if {![istarget x86_64-*] || ![is_lp64_target]} {
+    return 0
+}
+
+standard_testfile .S
+
+if {[prepare_for_testing "${testfile}.exp" "${testfile}" ${testfile}.S \
+	 nodebug]} {
+    return -1
+}
+
+gdb_test "trace ${testfile}.c:3" "Tracepoint $decimal .*" \
+    "set tracepoint"
+
+# This is a regression test for a crash when converting a DWARF
+# expression to AX.
+gdb_trace_setactions "set tracepoint actions" "" "collect x" "^$"



More information about the Gdb-patches mailing list