[PATCH] gdb/testsuite: write gdb.dwarf2/dw2-reg-undefined.exp test file in C
Simon Marchi
simon.marchi@efficios.com
Mon Aug 31 21:07:08 GMT 2020
The gdb.dwarf2/dw2-reg-undefined.S test file was generated from a C
source file (dw2-reg-undefined.c) using an x86-64 4.7.2 gcc. It was
then hand-modified to make the frame description entries say that some
registers are explicitly undefined / not saved.
This has downsides: it is hard to modify further, hard to read, and hard
to port to other architectures. I first wanted to change it so it would
use hand-written assembly (similar to
gdb.dwarf2/frame-inlined-in-outer-frame.exp). It then occured to me
that this one could very well be written in C, with just a minimum of
arch-specific things (CFI directives in asm() calls). This is what this
patch does.
I ported and tested it to i386 (using the unix/-m32 board on x86-64) and
AArch64.
Notes:
In the removed dw2-reg-undefined.S, it says:
/* This FDE entry, for stop_frame was modified to mark
registers 0 -> 6 as being undefined. */
Register with DWARF number 6 in x86-64 is rbp, and there is indeed a
DW_CFA_undefined directive for it:
.byte 0x7 /* DW_CFA_undefined */
.uleb128 0x6 /* ULEB128 register */
However there is another (compiler-generated) directive just below:
.uleb128 0x10
.byte 0x86
... which is effective at the point the program is stopped when the test
runs. So in my version, I simply didn't specify rbp as undefined.
The frame also says:
.byte 0x7 /* DW_CFA_undefined */
.uleb128 0x7 /* ULEB128 register */
where register 7 is rsp. So, rsp is actually undefined, the comment
doesn't mention it. I don't think it's relevant for the test, so I've
left this one out as well.
Change-Id: Id266a845235b89e21032b6d4e7b7b100b1c18265
---
gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.S | 522 ------------------
gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.c | 32 +-
.../gdb.dwarf2/dw2-reg-undefined.exp | 82 +--
3 files changed, 72 insertions(+), 564 deletions(-)
delete mode 100644 gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.S
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.S b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.S
deleted file mode 100644
index 01934dc64bf4..000000000000
--- a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.S
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- Copyright 2013-2020 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/>. */
-
- /* The FDE entry for "stop_frame" in the .debug_frame section has
- been hand modified to mark a set of registers as undefined.
- Otherwise this file is as generated by gcc 4.7.2 for x86_64. */
- .file "dw2-reg-undefined.c"
- .text
-.Ltext0:
- .globl stop_frame
- .type stop_frame, @function
-stop_frame:
-.LFB0:
- .file 1 "dw2-reg-undefined.c"
- .loc 1 19 0
- pushq %rbp
-.LCFI0:
- movq %rsp, %rbp
-.LCFI1:
- .loc 1 22 0
- popq %rbp
-.LCFI2:
- ret
-.LFE0:
- .size stop_frame, .-stop_frame
- .globl first_frame
- .type first_frame, @function
-first_frame:
-.LFB1:
- .loc 1 26 0
- pushq %rbp
-.LCFI3:
- movq %rsp, %rbp
-.LCFI4:
- .loc 1 27 0
- movl $0, %eax
- call stop_frame
- .loc 1 28 0
- popq %rbp
-.LCFI5:
- ret
-.LFE1:
- .size first_frame, .-first_frame
- .globl main
- .type main, @function
-main:
-.LFB2:
- .loc 1 32 0
- pushq %rbp
-.LCFI6:
- movq %rsp, %rbp
-.LCFI7:
- .loc 1 33 0
- movl $0, %eax
- call first_frame
- .loc 1 35 0
- movl $0, %eax
- .loc 1 36 0
- popq %rbp
-.LCFI8:
- ret
-.LFE2:
- .size main, .-main
- .section .debug_frame,"",@progbits
-.Lframe0:
- .long .LECIE0-.LSCIE0
-.LSCIE0:
- .long 0xffffffff
- .byte 0x1
- .string ""
- .uleb128 0x1
- .sleb128 -8
- .byte 0x10
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .byte 0x90
- .uleb128 0x1
- .align 8
-.LECIE0:
- /* This FDE entry, for stop_frame was modified to mark
- registers 0 -> 6 as being undefined. */
-.LSFDE0:
- .long .LEFDE0-.LASFDE0
-.LASFDE0:
- .long .Lframe0
- .quad .LFB0
- .quad .LFE0-.LFB0
-
- /* START OF NEW CONTENT. */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x0 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x1 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x2 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x3 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x4 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x5 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x6 /* ULEB128 register */
- .byte 0x7 /* DW_CFA_undefined */
- .uleb128 0x7 /* ULEB128 register */
- /* END OF NEW CONTENT. */
-
- .byte 0x4
- .long .LCFI0-.LFB0
- .byte 0xe
- .uleb128 0x10
- .byte 0x86
- .uleb128 0x2
- .byte 0x4
- .long .LCFI1-.LCFI0
- .byte 0xd
- .uleb128 0x6
- .byte 0x4
- .long .LCFI2-.LCFI1
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .align 8
-.LEFDE0:
-.LSFDE2:
- .long .LEFDE2-.LASFDE2
-.LASFDE2:
- .long .Lframe0
- .quad .LFB1
- .quad .LFE1-.LFB1
- .byte 0x4
- .long .LCFI3-.LFB1
- .byte 0xe
- .uleb128 0x10
- .byte 0x86
- .uleb128 0x2
- .byte 0x4
- .long .LCFI4-.LCFI3
- .byte 0xd
- .uleb128 0x6
- .byte 0x4
- .long .LCFI5-.LCFI4
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .align 8
-.LEFDE2:
-.LSFDE4:
- .long .LEFDE4-.LASFDE4
-.LASFDE4:
- .long .Lframe0
- .quad .LFB2
- .quad .LFE2-.LFB2
- .byte 0x4
- .long .LCFI6-.LFB2
- .byte 0xe
- .uleb128 0x10
- .byte 0x86
- .uleb128 0x2
- .byte 0x4
- .long .LCFI7-.LCFI6
- .byte 0xd
- .uleb128 0x6
- .byte 0x4
- .long .LCFI8-.LCFI7
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .align 8
-.LEFDE4:
- .section .eh_frame,"a",@progbits
-.Lframe1:
- .long .LECIE1-.LSCIE1
-.LSCIE1:
- .long 0
- .byte 0x1
- .string "zR"
- .uleb128 0x1
- .sleb128 -8
- .byte 0x10
- .uleb128 0x1
- .byte 0x3
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .byte 0x90
- .uleb128 0x1
- .align 8
-.LECIE1:
-.LSFDE7:
- .long .LEFDE7-.LASFDE7
-.LASFDE7:
- .long .LASFDE7-.Lframe1
- .long .LFB0
- .long .LFE0-.LFB0
- .uleb128 0
- .byte 0x4
- .long .LCFI0-.LFB0
- .byte 0xe
- .uleb128 0x10
- .byte 0x86
- .uleb128 0x2
- .byte 0x4
- .long .LCFI1-.LCFI0
- .byte 0xd
- .uleb128 0x6
- .byte 0x4
- .long .LCFI2-.LCFI1
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .align 8
-.LEFDE7:
-.LSFDE9:
- .long .LEFDE9-.LASFDE9
-.LASFDE9:
- .long .LASFDE9-.Lframe1
- .long .LFB1
- .long .LFE1-.LFB1
- .uleb128 0
- .byte 0x4
- .long .LCFI3-.LFB1
- .byte 0xe
- .uleb128 0x10
- .byte 0x86
- .uleb128 0x2
- .byte 0x4
- .long .LCFI4-.LCFI3
- .byte 0xd
- .uleb128 0x6
- .byte 0x4
- .long .LCFI5-.LCFI4
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .align 8
-.LEFDE9:
-.LSFDE11:
- .long .LEFDE11-.LASFDE11
-.LASFDE11:
- .long .LASFDE11-.Lframe1
- .long .LFB2
- .long .LFE2-.LFB2
- .uleb128 0
- .byte 0x4
- .long .LCFI6-.LFB2
- .byte 0xe
- .uleb128 0x10
- .byte 0x86
- .uleb128 0x2
- .byte 0x4
- .long .LCFI7-.LCFI6
- .byte 0xd
- .uleb128 0x6
- .byte 0x4
- .long .LCFI8-.LCFI7
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .align 8
-.LEFDE11:
- .text
-.Letext0:
- .section .debug_info,"",@progbits
-.Ldebug_info0:
- .long 0x8c
- .value 0x2
- .long .Ldebug_abbrev0
- .byte 0x8
- .uleb128 0x1
- .long .LASF2
- .byte 0x1
- .long .LASF3
- .long .LASF4
- .quad .Ltext0
- .quad .Letext0
- .long .Ldebug_line0
- .uleb128 0x2
- .byte 0x1
- .long .LASF0
- .byte 0x1
- .byte 0x12
- .quad .LFB0
- .quad .LFE0
- .long .LLST0
- .byte 0x1
- .uleb128 0x3
- .byte 0x1
- .long .LASF1
- .byte 0x1
- .byte 0x19
- .quad .LFB1
- .quad .LFE1
- .long .LLST1
- .byte 0x1
- .uleb128 0x4
- .byte 0x1
- .long .LASF5
- .byte 0x1
- .byte 0x1f
- .long 0x88
- .quad .LFB2
- .quad .LFE2
- .long .LLST2
- .byte 0x1
- .uleb128 0x5
- .byte 0x4
- .byte 0x5
- .string "int"
- .byte 0
- .section .debug_abbrev,"",@progbits
-.Ldebug_abbrev0:
- .uleb128 0x1
- .uleb128 0x11
- .byte 0x1
- .uleb128 0x25
- .uleb128 0xe
- .uleb128 0x13
- .uleb128 0xb
- .uleb128 0x3
- .uleb128 0xe
- .uleb128 0x1b
- .uleb128 0xe
- .uleb128 0x11
- .uleb128 0x1
- .uleb128 0x12
- .uleb128 0x1
- .uleb128 0x10
- .uleb128 0x6
- .byte 0
- .byte 0
- .uleb128 0x2
- .uleb128 0x2e
- .byte 0
- .uleb128 0x3f
- .uleb128 0xc
- .uleb128 0x3
- .uleb128 0xe
- .uleb128 0x3a
- .uleb128 0xb
- .uleb128 0x3b
- .uleb128 0xb
- .uleb128 0x11
- .uleb128 0x1
- .uleb128 0x12
- .uleb128 0x1
- .uleb128 0x40
- .uleb128 0x6
- .uleb128 0x2117
- .uleb128 0xc
- .byte 0
- .byte 0
- .uleb128 0x3
- .uleb128 0x2e
- .byte 0
- .uleb128 0x3f
- .uleb128 0xc
- .uleb128 0x3
- .uleb128 0xe
- .uleb128 0x3a
- .uleb128 0xb
- .uleb128 0x3b
- .uleb128 0xb
- .uleb128 0x11
- .uleb128 0x1
- .uleb128 0x12
- .uleb128 0x1
- .uleb128 0x40
- .uleb128 0x6
- .uleb128 0x2116
- .uleb128 0xc
- .byte 0
- .byte 0
- .uleb128 0x4
- .uleb128 0x2e
- .byte 0
- .uleb128 0x3f
- .uleb128 0xc
- .uleb128 0x3
- .uleb128 0xe
- .uleb128 0x3a
- .uleb128 0xb
- .uleb128 0x3b
- .uleb128 0xb
- .uleb128 0x49
- .uleb128 0x13
- .uleb128 0x11
- .uleb128 0x1
- .uleb128 0x12
- .uleb128 0x1
- .uleb128 0x40
- .uleb128 0x6
- .uleb128 0x2116
- .uleb128 0xc
- .byte 0
- .byte 0
- .uleb128 0x5
- .uleb128 0x24
- .byte 0
- .uleb128 0xb
- .uleb128 0xb
- .uleb128 0x3e
- .uleb128 0xb
- .uleb128 0x3
- .uleb128 0x8
- .byte 0
- .byte 0
- .byte 0
- .section .debug_loc,"",@progbits
-.Ldebug_loc0:
-.LLST0:
- .quad .LFB0-.Ltext0
- .quad .LCFI0-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 8
- .quad .LCFI0-.Ltext0
- .quad .LCFI1-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 16
- .quad .LCFI1-.Ltext0
- .quad .LCFI2-.Ltext0
- .value 0x2
- .byte 0x76
- .sleb128 16
- .quad .LCFI2-.Ltext0
- .quad .LFE0-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 8
- .quad 0
- .quad 0
-.LLST1:
- .quad .LFB1-.Ltext0
- .quad .LCFI3-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 8
- .quad .LCFI3-.Ltext0
- .quad .LCFI4-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 16
- .quad .LCFI4-.Ltext0
- .quad .LCFI5-.Ltext0
- .value 0x2
- .byte 0x76
- .sleb128 16
- .quad .LCFI5-.Ltext0
- .quad .LFE1-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 8
- .quad 0
- .quad 0
-.LLST2:
- .quad .LFB2-.Ltext0
- .quad .LCFI6-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 8
- .quad .LCFI6-.Ltext0
- .quad .LCFI7-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 16
- .quad .LCFI7-.Ltext0
- .quad .LCFI8-.Ltext0
- .value 0x2
- .byte 0x76
- .sleb128 16
- .quad .LCFI8-.Ltext0
- .quad .LFE2-.Ltext0
- .value 0x2
- .byte 0x77
- .sleb128 8
- .quad 0
- .quad 0
- .section .debug_aranges,"",@progbits
- .long 0x2c
- .value 0x2
- .long .Ldebug_info0
- .byte 0x8
- .byte 0
- .value 0
- .value 0
- .quad .Ltext0
- .quad .Letext0-.Ltext0
- .quad 0
- .quad 0
- .section .debug_line,"",@progbits
-.Ldebug_line0:
- .section .debug_str,"MS",@progbits,1
-.LASF0:
- .string "stop_frame"
-.LASF3:
- .string "dw2-reg-undefined.c"
-.LASF2:
- .string "GNU C 4.7.2"
-.LASF1:
- .string "first_frame"
-.LASF5:
- .string "main"
-.LASF4:
- .string "/home/username/src/gdb/testsuite/gdb.dwarf2"
- .ident "GCC: (GNU) 4.7.2"
- .section .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.c b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.c
index 1065d54833df..c976906373c0 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.c
+++ b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.c
@@ -14,21 +14,39 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-void
-stop_frame ()
+static void
+stop_frame (void)
{
- /* The debug information for this frame is modified in the accompanying
- .S file, to mark a set of registers as being undefined. */
+#if defined(__x86_64__)
+ asm (".cfi_undefined rax\n");
+ asm (".cfi_undefined rbx\n");
+ asm (".cfi_undefined rcx\n");
+ asm (".cfi_undefined rdx\n");
+ asm (".cfi_undefined rsi\n");
+ asm (".cfi_undefined rdi\n");
+#elif defined(__i386__)
+ asm (".cfi_undefined eax\n");
+ asm (".cfi_undefined ebx\n");
+ asm (".cfi_undefined ecx\n");
+ asm (".cfi_undefined edx\n");
+#elif defined(__aarch64__)
+ asm (".cfi_undefined x0\n");
+ asm (".cfi_undefined x1\n");
+ asm (".cfi_undefined x2\n");
+ asm (".cfi_undefined x3\n");
+#else
+# error "unsupported architecture"
+#endif
}
-void
-first_frame ()
+static void
+first_frame (void)
{
stop_frame ();
}
int
-main ()
+main (void)
{
first_frame ();
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
index 75ea1f7b88ac..c28a0345bf50 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
@@ -19,14 +19,9 @@ 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 .c
-standard_testfile .S
-
-if { [prepare_for_testing "failed to prepare" $testfile $srcfile {nodebug nopie}] } {
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
return -1
}
@@ -35,54 +30,71 @@ if ![runto stop_frame] {
return -1
}
+if { [istarget x86_64-*] } {
+ if { [is_x86_like_target] } {
+ set undefined_regs {eax ebx ecx edx}
+ set defined_regs {esi edi}
+ } else {
+ set undefined_regs {rax rbx rcx rdx rsi rdi}
+ set defined_regs {r8 r9}
+ }
+} elseif { [istarget aarch64-*] } {
+ set undefined_regs {x0 x1 x2 x3}
+ set defined_regs {x4 x5}
+}
+
gdb_test "bt" "#0 (0x\[0-9a-f\]+ in )?stop_frame \[^\r\n\]*\r\n#1 \[^\r\n\]*first_frame \[^\r\n\]*\r\n#2 \[^\r\n\]*main\[^\r\n\]*" \
"backtrace from stop_frame"
-for {set f 0} {$f < 3} {incr f} {
+foreach_with_prefix f { 0 1 2 } {
if {${f} == 0} {
- set pattern_rax_rbx_rcx_print "$hex"
- set pattern_rax_rbx_rcx_info "$hex\\s+$decimal"
- set pattern_r8_r9_print "$hex"
- set pattern_r8_r9_info "$hex\\s+$decimal"
+ set pattern_undefined_print "$hex"
+ set pattern_undefined_info "$hex\\s+-?$decimal"
+ set pattern_defined_print "$hex"
+ set pattern_defined_info "$hex\\s+-?$decimal"
} else {
- set pattern_rax_rbx_rcx_print "<not saved>"
- set pattern_rax_rbx_rcx_info "<not saved>"
- set pattern_r8_r9_print "$hex"
- set pattern_r8_r9_info "$hex\\s+$decimal"
+ set pattern_undefined_print "<not saved>"
+ set pattern_undefined_info "<not saved>"
+ set pattern_defined_print "$hex"
+ set pattern_defined_info "$hex\\s+-?$decimal"
}
# Select frame.
- gdb_test "frame ${f}" "#${f}.*" "switch to frame ${f}"
-
- gdb_test "p/x \$rax" ".*$pattern_rax_rbx_rcx_print.*" \
- "print \$rax in frame ${f}"
- gdb_test "p/x \$rbx" "$pattern_rax_rbx_rcx_print" \
- "print \$rbx in frame ${f}"
- gdb_test "p/x \$rcx" "$pattern_rax_rbx_rcx_print" \
- "print \$rcx in frame ${f}"
+ gdb_test "frame ${f}" "#${f}.*"
- gdb_test "p/x \$r8" "$pattern_r8_r9_print" "print \$r8 in frame ${f}"
- gdb_test "p/x \$r9" "$pattern_r8_r9_print" "print \$r9 in frame ${f}"
+ foreach reg $undefined_regs {
+ gdb_test "p/x \$${reg}" ".*$pattern_undefined_print.*"
+ }
+ foreach reg $defined_regs {
+ gdb_test "p/x \$${reg}" "$pattern_defined_print"
+ }
# Display register values.
- gdb_test "info registers rax rbx rcx r8 r9" \
- [multi_line "rax\\s+${pattern_rax_rbx_rcx_info}\\s*" \
- "rbx\\s+${pattern_rax_rbx_rcx_info}\\s*" \
- "rcx\\s+${pattern_rax_rbx_rcx_info}\\s*" \
- "r8\\s+${pattern_r8_r9_info}\\s*" \
- "r9\\s+${pattern_r8_r9_info}\\s*"] \
- "Check values of rax, rbx, rcx, r8, r9 in frame ${f}"
+ set pattern_lines {}
+
+ foreach reg $undefined_regs {
+ lappend pattern_lines "${reg}\\s+${pattern_undefined_info}\\s*"
+ }
+
+ foreach reg $defined_regs {
+ lappend pattern_lines "${reg}\\s+${pattern_defined_info}\\s*"
+ }
+
+ set pattern [multi_line {*}$pattern_lines]
+ gdb_test "info registers [join $undefined_regs] [join $defined_regs]" $pattern
}
# Test that the debug log statement in frame_unwind_register_value produces
# "not saved" and not "optimized out".
+set undefined_reg [lindex ${undefined_regs} 0]
gdb_test "set debug frame 1"
-gdb_test {print $rax} {frame_unwind_register_value[^\r\n]+rax[^\r\n]+not saved.*}
+gdb_test "print \$${undefined_reg}" \
+ "frame_unwind_register_value\[^\r\n\]+${undefined_reg}\[^\r\n\]+not saved.*"
gdb_test "set debug frame 0"
# Test that history values show "not saved" and not "optimized out".
gdb_test "print" " = <not saved>"
# Test that convenience variables _don't_ show "not saved".
-gdb_test {print $foo = $rax} " = <optimized out>"
+gdb_test "print \$foo = \$${undefined_reg}" "= <optimized out>"
--
2.26.2
More information about the Gdb-patches
mailing list