It's possible to inspect an already running janet process via gdb, but janet
needs to have been compiled with debugging info beforehand.
- Ensure the operating system allows gdb connecting to a running process
- Compile janet with debugging info
- Create sample janet source file
- Run janet with sample file and determine the janet process's PID
- Connect to the process using gdb
- Perform some fiddling in gdb in preparation
- Have fun exploring with gdb
-
From some version of Linux, it may be necessary as root to:
# echo 1 > /proc/sys/kernel/yama/ptrace_scope
If the previous command was necessary, when done with these experiments, you may (as root again) want to:
# echo 0 > /proc/sys/kernel/yama/ptrace_scope
-
Get janet source ready -- for sake of later reference, checkout this commit
$ git clone https://github.com/janet-lang/janet $ cd janet $ git checkout a78cbd91dad1066ec82c31cb74b6c4bf2ea44d1b
-
Compile janet with debugging info -- but first tweak
Makefile
$ sed -i "s/^CFLAGS?=-O2/CFLAGS?=-O0 -g3/" Makefile $ make
-
Arrange to have a janet file with
(os/sleep 60)
at the top, e.g.$ echo "(os/sleep 60) (pp {:a 1})" > test.janet
-
Use the debug build of janet to run the test file
$ ./build/janet test.janet
-
In another terminal, determine the process id of the running janet process
$ pidof janet
If there is more than one janet process, use
ps
to figure out the relevant one. -
Start gdb using the determined process id (here it is assumed there is only one running janet process) -- once connected, the janet process may be "paused"
$ gdb -quiet -p `pidof janet` Attaching to process 216859 Reading symbols from /home/user/.local/bin/janet... (No debugging symbols found in /home/user/.local/bin/janet) Reading symbols from /usr/lib/libm.so.6... (No debugging symbols found in /usr/lib/libm.so.6) Reading symbols from /usr/lib/libpthread.so.0... (No debugging symbols found in /usr/lib/libpthread.so.0) [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/libthread_db.so.1". Reading symbols from /usr/lib/librt.so.1... (No debugging symbols found in /usr/lib/librt.so.1) Reading symbols from /usr/lib/libdl.so.2... (No debugging symbols found in /usr/lib/libdl.so.2) Reading symbols from /usr/lib/libc.so.6... (No debugging symbols found in /usr/lib/libc.so.6) Reading symbols from /lib64/ld-linux-x86-64.so.2... (No debugging symbols found in /lib64/ld-linux-x86-64.so.2) 0x00007ff506619762 in read () from /usr/lib/libpthread.so.0
-
Set an appropriate breakpoint -- here
cfun_io_printf
is used becausepp
(which is used in the test file) callsprintf
which is in turn implemented in terms ofcfun_io_printf
(gdb) b cfun_io_printf Breakpoint 1 at 0x5627ea734fe9: file src/core/io.c, line 631.
-
Resume the process via
c
(gdb) c Continuing. Breakpoint 1, cfun_io_printf (argc=2, argv=0x559c10170568) at src/core/io.c:631 631 return cfun_io_printf_impl(argc, argv, 1, "out", stdout);
-
Have fun exploring :)