本机OCaml编译器公开用于控制是否发出调试信息的选项。例如-g
控制是否记录重建异常回溯所需的信息。是否有选项发出gdb
来将断点与源信息(例如文件名和行号)相关联所需的调试信息?
我认为OCaml目前不是gdb
的一种完全受支持的语言,并且无法漂亮地打印值或评估OCaml表达式。没关系,我只是想知道如何配置ocamlopt
编译器或gdb
以便gdb
可以找到源文件。理想情况下,我希望能够看到存在OCaml运行时的OCaml源代码和C源文件(即,通过手动而不是通过OPAM构建编译器时)。
例如,
(* hello.ml *)
let main () =
Printf.printf "hi there\n%!";;
let () = main ()
使用corebuild hello.native
进行编译,生成指向可执行文件hello.native
的符号链接。
然后,在启动gdb
时:
(gdb) file hello.native
Reading symbols from hello.native...done.
(gdb) start
Temporary breakpoint 1 at 0x405580: file main.c, line 32.
Starting program: /home/g/ws/tmp/ocaml/hello/hello.native
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main (argc=0x1, argv=0x7fffffffdaf8) at main.c:32
32 main.c: No such file or directory.
我们可以看到它无法确定文件的位置。
当您按下C-x a
并将gdb
切换到tui模式时,消息[ No Source Available ]
在顶部窗格中可见。
答案 0 :(得分:1)
使用dir
中的gdb
指令将其指向OCaml运行时源代码所在的地方,例如
(gdb) dir ~/warehouse/ocaml/byterun/
Source directories searched: /home/ivg/warehouse/ocaml/byterun:$cdir:$cwd
(gdb) l
27 #endif
28
29 CAMLextern void caml_main (char_os **);
30
31 #ifdef _WIN32
32 CAMLextern void caml_expand_command_line (int *, wchar_t ***);
33
34 int wmain(int argc, wchar_t **argv)
35 #else
36 int main(int argc, char **argv)
更多提示。您可以将程序与调试运行时链接,例如
ocamlopt -runtime-variant x -g hello.ml -o hello
虽然不会嵌入源代码。
此外,OCaml对gdb也有很好的支持,您可以步进,回溯甚至观察源代码。唯一的问题是名称通常会混乱,因此很难设置断点。但是,您可以使用objdump
对文件进行反向工程。如果使用-g
选项构建,则很容易:
$ objdump -S hello | grep hello.ml -A 10
(* hello.ml *)
let main () =
404a70: 48 8d 1d 81 a6 24 00 lea 0x24a681(%rip),%rbx # 64f0f8 <camlHello__5>
404a77: 48 8d 05 da b3 24 00 lea 0x24b3da(%rip),%rax # 64fe58 <camlPervasives>
Printf.printf "hi there\n%!";;
404a7e: 48 8b 80 d0 00 00 00 mov 0xd0(%rax),%rax
404a85: e9 66 ae 01 00 jmpq 41f8f0 <camlPrintf__fprintf_1294>
404a8a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
0000000000404a90 <camlHello__entry>: