Skip to content

Commit

Permalink
Add GDB Linux AMD64, ARM64 and RISC-V test cases for backtraces.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmcgilchrist committed Jul 4, 2024
1 parent e2e8baf commit 8f9c188
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 4 deletions.
10 changes: 10 additions & 0 deletions ocamltest/builtin_actions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ let not_bsd = make
"not on a BSD system"
"on a BSD system")

let linux_system = "linux"

let linux = make
~name:"linux"
~description:"Pass if running on a Linux system"
(Actions_helpers.pass_or_skip (Ocamltest_config.system = linux_system)
"on a Linux system"
"not on a Linux system")

let macos_system = "macosx"

let macos = make
Expand Down Expand Up @@ -368,6 +377,7 @@ let _ =
not_bsd;
macos;
not_macos_amd64_tsan;
linux;
arch32;
arch64;
has_symlink;
Expand Down
13 changes: 10 additions & 3 deletions ocamltest/ocaml_actions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ let debug debugger_type log env =
| GDB -> [
Ocaml_commands.gdb_run;
Ocaml_flags.gdb_default_flags;
"-x " ^ (Environments.safe_lookup Ocaml_variables.debugger_script env);
program ]
| Bytecode -> [
Ocaml_commands.ocamlrun_ocamldebug;
Expand Down Expand Up @@ -589,10 +590,16 @@ let debug debugger_type log env =
end

let ocamldebug =
Actions.make ~name:"ocamldebug" ~description:"Run ocamldebug on the program" (debug Bytecode)
Actions.make ~name:"ocamldebug"
~description:"Run ocamldebug on the program" (debug Bytecode)

let lldb = Actions.make ~name:"lldb" ~description:"Run LLDB on the program" (debug LLDB)
let gdb = Actions.make ~name:"gdb" ~description:"Run GDB on the program" (debug GDB)
let lldb =
Actions.make ~name:"lldb"
~description:"Run LLDB on the program" (debug LLDB)

let gdb =
Actions.make ~name:"gdb"
~description:"Run GDB on the program" (debug GDB)

let objinfo log env =
let tools_directory = Ocaml_directories.tools in
Expand Down
2 changes: 1 addition & 1 deletion ocamltest/ocaml_flags.ml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ let ocamlobjinfo_default_flags = "-null-crc"

let lldb_default_flags = "--no-use-colors"

let gdb_default_flags = ""
let gdb_default_flags = "--quiet --batch"
15 changes: 15 additions & 0 deletions testsuite/tests/native-debugger/gdb-script
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
break *(&caml_start_program+0)
break caml_program
break ocaml_to_c
break meander.ml:5
set debuginfod enabled off
run
backtrace
continue
backtrace
continue
backtrace
continue
backtrace
continue
quit
7 changes: 7 additions & 0 deletions testsuite/tests/native-debugger/has_gdb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
if ! which gdb > /dev/null 2>&1; then
echo "gdb not available" > ${ocamltest_response}
exit ${TEST_SKIP}
else
exit ${TEST_PASS}
fi
19 changes: 19 additions & 0 deletions testsuite/tests/native-debugger/linux-gdb-amd64-test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(* TEST
native-compiler;
linux;
arch_amd64;
script = "sh ${test_source_directory}/has_gdb.sh";
script;
readonly_files = "meander.ml meander_c.c lldb_test.py";
setup-ocamlopt.byte-build-env;
program = "${test_build_directory}/meander";
flags = "-g";
all_modules = "meander.ml meander_c.c";
ocamlopt.byte;
debugger_script = "${test_source_directory}/gdb-script";
gdb;
script = "sh ${test_source_directory}/sanitize.sh ${test_source_directory} \
${test_build_directory} ${ocamltest_response} linux-gdb-amd64-test";
script;
check-program-output;
*)
60 changes: 60 additions & 0 deletions testsuite/tests/native-debugger/linux-gdb-amd64-test.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Breakpoint 1 at 0x00000000000000
Breakpoint 2 at 0x00000000000000
Breakpoint 3 at 0x00000000000000: file meander_c.c, line 4.
Breakpoint 4 at 0x00000000000000: file meander.ml, line 5.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/$ARCH-linux-gnu/libthread_db.so.1".

Breakpoint 1, <signal handler called>
#0 <signal handler called>
#1 0x00000000000000 in caml_startup_common (pooling=<optimised out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#2 caml_startup_common (argv=0x00000000000000, pooling=<optimised out>) at runtime/startup_nat.c:87
#3 0x00000000000000 in caml_startup_exn (argv=<optimised out>) at runtime/startup_nat.c:135
#4 caml_startup (argv=<optimised out>) at runtime/startup_nat.c:140
#5 caml_main (argv=<optimised out>) at runtime/startup_nat.c:147
#6 0x00000000000000 in main (argc=<optimised out>, argv=<optimised out>) at runtime/main.c:37

Breakpoint 2, 0x00000000000000 in caml_program ()
#0 0x00000000000000 in caml_program ()
#1 <signal handler called>
#2 0x00000000000000 in caml_startup_common (pooling=<optimised out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#3 caml_startup_common (argv=0x00000000000000, pooling=<optimised out>) at runtime/startup_nat.c:87
#4 0x00000000000000 in caml_startup_exn (argv=<optimised out>) at runtime/startup_nat.c:135
#5 caml_startup (argv=<optimised out>) at runtime/startup_nat.c:140
#6 caml_main (argv=<optimised out>) at runtime/startup_nat.c:147
#7 0x00000000000000 in main (argc=<optimised out>, argv=<optimised out>) at runtime/main.c:37

Breakpoint 3, ocaml_to_c (unit=1) at meander_c.c:4
4 value ocaml_to_c (value unit) {
#0 ocaml_to_c (unit=1) at meander_c.c:4
#1 <signal handler called>
#2 0x00000000000000 in camlMeander.omain_278 () at meander.ml:10
#3 0x00000000000000 in camlMeander.entry () at meander.ml:13
#4 0x00000000000000 in caml_program ()
#5 <signal handler called>
#6 0x00000000000000 in caml_startup_common (pooling=<optimised out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#7 caml_startup_common (argv=0x00000000000000, pooling=<optimised out>) at runtime/startup_nat.c:87
#8 0x00000000000000 in caml_startup_exn (argv=<optimised out>) at runtime/startup_nat.c:135
#9 caml_startup (argv=<optimised out>) at runtime/startup_nat.c:140
#10 caml_main (argv=<optimised out>) at runtime/startup_nat.c:147
#11 0x00000000000000 in main (argc=<optimised out>, argv=<optimised out>) at runtime/main.c:37

Breakpoint 4, camlMeander.c_to_ocaml_273 () at meander.ml:5
5 let c_to_ocaml () = raise E1
#0 camlMeander.c_to_ocaml_273 () at meander.ml:5
#1 <signal handler called>
#2 0x00000000000000 in caml_callback_exn (closure=<optimised out>, arg=<optimised out>, arg@entry=1) at runtime/callback.c:206
#3 0x00000000000000 in caml_callback (closure=<optimised out>, arg=arg@entry=1) at runtime/callback.c:347
#4 0x00000000000000 in ocaml_to_c (unit=<optimised out>) at meander_c.c:5
#5 <signal handler called>
#6 0x00000000000000 in camlMeander.omain_278 () at meander.ml:10
#7 0x00000000000000 in camlMeander.entry () at meander.ml:13
#8 0x00000000000000 in caml_program ()
#9 <signal handler called>
#10 0x00000000000000 in caml_startup_common (pooling=<optimised out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#11 caml_startup_common (argv=0x00000000000000, pooling=<optimised out>) at runtime/startup_nat.c:87
#12 0x00000000000000 in caml_startup_exn (argv=<optimised out>) at runtime/startup_nat.c:135
#13 caml_startup (argv=<optimised out>) at runtime/startup_nat.c:140
#14 caml_main (argv=<optimised out>) at runtime/startup_nat.c:147
#15 0x00000000000000 in main (argc=<optimised out>, argv=<optimised out>) at runtime/main.c:37
[Inferior 1 (process XXXX) exited normally]
19 changes: 19 additions & 0 deletions testsuite/tests/native-debugger/linux-gdb-arm64-test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(* TEST
native-compiler;
linux;
arch_arm64;
script = "sh ${test_source_directory}/has_gdb.sh";
script;
readonly_files = "meander.ml meander_c.c lldb_test.py";
setup-ocamlopt.byte-build-env;
program = "${test_build_directory}/meander";
flags = "-g";
all_modules = "meander.ml meander_c.c";
ocamlopt.byte;
debugger_script = "${test_source_directory}/gdb-script";
gdb;
script = "sh ${test_source_directory}/sanitize.sh ${test_source_directory} \
${test_build_directory} ${ocamltest_response} linux-gdb-arm64-test";
script;
check-program-output;
*)
60 changes: 60 additions & 0 deletions testsuite/tests/native-debugger/linux-gdb-arm64-test.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Breakpoint 1 at 0x00000000000000
Breakpoint 2 at 0x00000000000000
Breakpoint 3 at 0x00000000000000: file meander_c.c, line 5.
Breakpoint 4 at 0x00000000000000: file meander.ml, line 5.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".

Breakpoint 1, <signal handler called>
#0 <signal handler called>
#1 0x00000000000000 in caml_startup_common (pooling=0, argv=0x00000000000000) at runtime/startup_nat.c:128
#2 caml_startup_common (argv=0x00000000000000, pooling=0) at runtime/startup_nat.c:87
#3 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#4 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#5 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#6 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37

Breakpoint 2, 0x00000000000000 in caml_program ()
#0 0x00000000000000 in caml_program ()
#1 <signal handler called>
#2 0x00000000000000 in caml_startup_common (pooling=0, argv=0x00000000000000) at runtime/startup_nat.c:128
#3 caml_startup_common (argv=0x00000000000000, pooling=0) at runtime/startup_nat.c:87
#4 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#5 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#6 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#7 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37

Breakpoint 3, ocaml_to_c (unit=1) at meander_c.c:5
5 caml_callback(*caml_named_value
#0 ocaml_to_c (unit=1) at meander_c.c:5
#1 <signal handler called>
#2 0x00000000000000 in camlMeander.omain_278 () at meander.ml:10
#3 0x00000000000000 in camlMeander.entry () at meander.ml:13
#4 0x00000000000000 in caml_program ()
#5 <signal handler called>
#6 0x00000000000000 in caml_startup_common (pooling=4, argv=0x00000000000000) at runtime/startup_nat.c:128
#7 caml_startup_common (argv=0x00000000000000, pooling=4) at runtime/startup_nat.c:87
#8 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#9 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#10 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#11 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37

Breakpoint 4, camlMeander.c_to_ocaml_273 () at meander.ml:5
5 let c_to_ocaml () = raise E1
#0 camlMeander.c_to_ocaml_273 () at meander.ml:5
#1 <signal handler called>
#2 0x00000000000000 in caml_callback_exn (closure=<optimized out>, arg=<optimized out>, arg@entry=1) at runtime/callback.c:206
#3 0x00000000000000 in caml_callback (closure=<optimized out>, arg=arg@entry=1) at runtime/callback.c:347
#4 0x00000000000000 in ocaml_to_c (unit=<optimized out>) at meander_c.c:5
#5 <signal handler called>
#6 0x00000000000000 in camlMeander.omain_278 () at meander.ml:10
#7 0x00000000000000 in camlMeander.entry () at meander.ml:13
#8 0x00000000000000 in caml_program ()
#9 <signal handler called>
#10 0x00000000000000 in caml_startup_common (pooling=4, argv=0x00000000000000) at runtime/startup_nat.c:128
#11 caml_startup_common (argv=0x00000000000000, pooling=4) at runtime/startup_nat.c:87
#12 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#13 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#14 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#15 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37
[Inferior 1 (process XXXX) exited normally]
19 changes: 19 additions & 0 deletions testsuite/tests/native-debugger/linux-gdb-riscv-test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(* TEST
native-compiler;
linux;
arch_riscv;
script = "sh ${test_source_directory}/has_gdb.sh";
script;
readonly_files = "meander.ml meander_c.c lldb_test.py";
setup-ocamlopt.byte-build-env;
program = "${test_build_directory}/meander";
flags = "-g";
all_modules = "meander.ml meander_c.c";
ocamlopt.byte;
debugger_script = "${test_source_directory}/gdb-script";
gdb;
script = "sh ${test_source_directory}/sanitize.sh ${test_source_directory} \
${test_build_directory} ${ocamltest_response} linux-gdb-riscv-test";
script;
check-program-output;
*)
60 changes: 60 additions & 0 deletions testsuite/tests/native-debugger/linux-gdb-riscv-test.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Breakpoint 1 at 0x00000000000000
Breakpoint 2 at 0x00000000000000
Breakpoint 3 at 0x00000000000000: file meander_c.c, line 5.
Breakpoint 4 at 0x00000000000000: file meander.ml, line 5.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/$ARCH-linux-gnu/libthread_db.so.1".

Breakpoint 1, <signal handler called>
#0 <signal handler called>
#1 0x00000000000000 in caml_startup_common (pooling=<optimized out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#2 caml_startup_common (argv=0x00000000000000, pooling=<optimized out>) at runtime/startup_nat.c:87
#3 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#4 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#5 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#6 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37

Breakpoint 2, 0x00000000000000 in caml_program ()
#0 0x00000000000000 in caml_program ()
#1 <signal handler called>
#2 0x00000000000000 in caml_startup_common (pooling=<optimized out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#3 caml_startup_common (argv=0x00000000000000, pooling=<optimized out>) at runtime/startup_nat.c:87
#4 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#5 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#6 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#7 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37

Breakpoint 3, ocaml_to_c (unit=1) at meander_c.c:5
5 caml_callback(*caml_named_value
#0 ocaml_to_c (unit=1) at meander_c.c:5
#1 <signal handler called>
#2 0x00000000000000 in camlMeander.omain_278 () at meander.ml:10
#3 0x00000000000000 in camlMeander.entry () at meander.ml:13
#4 0x00000000000000 in caml_program ()
#5 <signal handler called>
#6 0x00000000000000 in caml_startup_common (pooling=<optimized out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#7 caml_startup_common (argv=0x00000000000000, pooling=<optimized out>) at runtime/startup_nat.c:87
#8 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#9 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#10 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#11 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37

Breakpoint 4, camlMeander.c_to_ocaml_273 () at meander.ml:5
5 let c_to_ocaml () = raise E1
#0 camlMeander.c_to_ocaml_273 () at meander.ml:5
#1 <signal handler called>
#2 0x00000000000000 in caml_callback_exn (closure=<optimized out>, arg=<optimized out>, arg@entry=1) at runtime/callback.c:206
#3 0x00000000000000 in caml_callback (closure=<optimized out>, arg=arg@entry=1) at runtime/callback.c:347
#4 0x00000000000000 in ocaml_to_c (unit=<optimized out>) at meander_c.c:5
#5 <signal handler called>
#6 0x00000000000000 in camlMeander.omain_278 () at meander.ml:10
#7 0x00000000000000 in camlMeander.entry () at meander.ml:13
#8 0x00000000000000 in caml_program ()
#9 <signal handler called>
#10 0x00000000000000 in caml_startup_common (pooling=<optimized out>, argv=0x00000000000000) at runtime/startup_nat.c:128
#11 caml_startup_common (argv=0x00000000000000, pooling=<optimized out>) at runtime/startup_nat.c:87
#12 0x00000000000000 in caml_startup_exn (argv=<optimized out>) at runtime/startup_nat.c:135
#13 caml_startup (argv=<optimized out>) at runtime/startup_nat.c:140
#14 caml_main (argv=<optimized out>) at runtime/startup_nat.c:147
#15 0x00000000000000 in main (argc=<optimized out>, argv=<optimized out>) at runtime/main.c:37
[Inferior 1 (process XXXX) exited normally]
13 changes: 13 additions & 0 deletions testsuite/tests/native-debugger/meander.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
external ocaml_to_c
: unit -> int = "ocaml_to_c"
exception E1
exception E2
let c_to_ocaml () = raise E1
let _ = Callback.register
"c_to_ocaml" c_to_ocaml
let omain () =
try (* h1 *)
try (* h2 *) ocaml_to_c ()
with E2 -> 0
with E1 -> 42
let _ = assert (omain () = 42)
8 changes: 8 additions & 0 deletions testsuite/tests/native-debugger/meander_c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <caml/mlvalues.h>
#include <caml/callback.h>

value ocaml_to_c (value unit) {
caml_callback(*caml_named_value
("c_to_ocaml"), Val_unit);
return Val_int(0);
}
31 changes: 31 additions & 0 deletions testsuite/tests/native-debugger/sanitize.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Replace sections of LLDB output
# This primarily looks for hex addresses, process ids, filepaths and
# other specific details of the machine the test is running on.
{
# Replace single quoted file paths
gsub(/'(.*)'/,"'XXXX'")

# Replace target create for executable
gsub(/target create "(.*)"/,"target create \"XXXX\"")

# Replace hex addresses, not offset values less than 4 digits.
gsub(/0x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]+/, "0x00000000000000")

# Sanitise executable name in image lookup
gsub("5 matches found in /(.*):$", "5 matches found in XXXX")

# Replace debug process forked by lldb
gsub("Process ([0-9]+)", "Process XXXX")

# Replace debug process forked by gdb
gsub("[Inferior 1 (process [0-9]+) exited normally]", "[Inferior 1 (process XXXX) exited normally]")

# Replace architecture identifiers
gsub("(x86_64)", "$ARCH")
gsub("(arm64)", "$ARCH")
gsub("(riscv64)", "$ARCH")

# Replace printed match results
gsub("1 match found in /(.*):$", "1 match found in \"XXXX\":")
print $0
}
12 changes: 12 additions & 0 deletions testsuite/tests/native-debugger/sanitize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

test_source_directory="$1"
test_build_directory="$2"
ocamltest_response="$3"
test_name="$4"

awk -f ${test_source_directory}/sanitize.awk \
${test_build_directory}/${test_name}.opt.output > ${test_build_directory}/${test_name}.opt.awk.output

mv ${test_build_directory}/${test_name}.opt.output ${test_build_directory}/${test_name}.opt.output.bak
cp ${test_build_directory}/${test_name}.opt.awk.output ${test_build_directory}/${test_name}.opt.output

0 comments on commit 8f9c188

Please sign in to comment.