Closed acodervic closed 7 months ago
Is it a problem to debug Nelua with gdb/lldb?
--sanitize
For quick fixes, you can use --sanitize
to debug most memory corruption errors and also have a backtrace of aborts and crashes.
For example, given the following test.nelua
buggy program:
local a: [4]integer
local function foo(i: integer, x: integer)
a[i] = i
end
foo(-1, 2)
print 'finished!'
Lets run it:
$ nelua test.nelua
array index: position out of bounds
Aborted (SIGABRT)
It aborted because of out of bounds error, but where it happened? Let's debug with --sanitize
:
$ nelua --sanitize test.nelua
array index: position out of bounds
/home/bart/.cache/nelua/test.c:164:3: runtime error: execution reached an unreachable program point
#0 0x5d6b38f8427c in nelua_abort /home/bart/.cache/nelua/test.c:164
#1 0x5d6b38f843ee in nelua_panic_cstring /home/bart/.cache/nelua/test.c:171
#2 0x5d6b38f84446 in nelua_assert_bounds_nlint64 /home/bart/.cache/nelua/test.c:175
#3 0x5d6b38f84446 in test_foo /home/bart/.cache/nelua/test.c:180
#4 0x5d6b38f847d4 in nelua_main /home/bart/.cache/nelua/test.c:190
#5 0x5d6b38f8482e in main /home/bart/.cache/nelua/test.c:195
#6 0x7e245aa43ccf (/usr/lib/libc.so.6+0x25ccf) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
#7 0x7e245aa43d89 in __libc_start_main (/usr/lib/libc.so.6+0x25d89) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
#8 0x5d6b38f84184 in _start (/home/bart/.cache/nelua/test+0x2184) (BuildId: 9693d1c0f62bf813909741afbe9e72c06622061c)
From reading the backgtrace it happend inside #3 test_foo
called from #4 nelua_main
. test_foo
is the name of the function (foo
) prefixed with the name of the program (test
). nelua_main
is the function that executes all top scope code. But what were the values and exactly where in foo
?
--debug
If we want more details we can combine --sanitize --debug
, the --debug
option will run through gdb and show even more details about backtrace:
$ nelua --sanitize --debug test.nelua
Reading symbols from /home/bart/.cache/nelua/test...
Breakpoint 1 at 0x1060
Starting program: /home/bart/.cache/nelua/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
array index: position out of bounds
Breakpoint 1, 0x00007ffff76423e1 in abort () from /usr/lib/libc.so.6
#0 0x00007ffff76423e1 in abort () from /usr/lib/libc.so.6
#1 0x0000555555555225 in nelua_abort () at /home/bart/.cache/nelua/test.c:165
165 abort();
#2 0x0000555555555355 in nelua_panic_cstring (s=0x555555556060 "array index: position out of bounds") at /home/bart/.cache/nelua/test.c:171
171 nelua_abort();
#3 0x00005555555553ac in nelua_assert_bounds_nlint64 (len=4, index=-1) at /home/bart/.cache/nelua/test.c:175
175 nelua_panic_cstring("array index: position out of bounds");
#4 test_foo (i=-1, x=2) at /home/bart/.cache/nelua/test.c:180
180 test_a.v[nelua_assert_bounds_nlint64(i, 4)] = i;
#5 0x00005555555556ae in nelua_main (argc=1, argv=0x7fffffffda28) at /home/bart/.cache/nelua/test.c:190
190 test_foo(-1, 2);
#6 0x0000555555555708 in main (argc=1, argv=0x7fffffffda28) at /home/bart/.cache/nelua/test.c:195
195 return nelua_main(argc, argv);
Ok the values of i
was -1
and x
was 2
as seen in #4 test_foo (i=-1, x=2) at /home/bart/.cache/nelua/test.c:180
.
If we want to dive further we can open the file /home/bart/.cache/nelua/test.c:180
and inspect the C code:
void play_foo(int64_t i, int64_t x) {
play_a.v[nelua_assert_bounds_nlint64(i, 4)] = i;
}
You can go further and manually run gdb
and debug on you own:
gdb /home/bart/.cache/nelua/test -ex run -ex bt
GNU gdb (GDB) 14.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/bart/.cache/nelua/test...
Starting program: /home/bart/.cache/nelua/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
array index: position out of bounds
Program received signal SIGABRT, Aborted.
0x00007ffff76ab32c in ?? () from /usr/lib/libc.so.6
#0 0x00007ffff76ab32c in ?? () from /usr/lib/libc.so.6
#1 0x00007ffff765a6c8 in raise () from /usr/lib/libc.so.6
#2 0x00007ffff76424b8 in abort () from /usr/lib/libc.so.6
#3 0x0000555555555225 in nelua_abort () at /home/bart/.cache/nelua/test.c:165
#4 0x0000555555555355 in nelua_panic_cstring (s=0x555555556060 "array index: position out of bounds") at /home/bart/.cache/nelua/test.c:171
#5 0x00005555555553ac in nelua_assert_bounds_nlint64 (len=4, index=-1) at /home/bart/.cache/nelua/test.c:175
#6 play_foo (i=-1, x=2) at /home/bart/.cache/nelua/test.c:180
#7 0x00005555555556ae in nelua_main (argc=1, argv=0x7fffffffda98) at /home/bart/.cache/nelua/test.c:190
#8 0x0000555555555708 in main (argc=1, argv=0x7fffffffda98) at /home/bart/.cache/nelua/test.c:195
(gdb) frame 6
#6 play_foo (i=-1, x=2) at /home/bart/.cache/nelua/test.c:180
180 play_a.v[nelua_assert_bounds_nlint64(i, 4)] = i;
(gdb) p i
$1 = -1
(gdb) p x
$2 = 2
As you noticed, debugging happens at a lower level C code. You might complain that you need to debug in another language, but it's often common even in C/C++ to debug nasty bugs in assembly machine level code, so debugging in a another lower code is not novel, and typically you only need to do this in very nasty situations.
Most case having the name of the function you crashed and its input values is enough, so you may not really need to understand much of C. The same happens when debugging C programs with assembly x86 machine code, while most developers don't fully understand x86 machine code, they sometimes reason about assembly machine code when debugging.
It's possible to create compiler plugins that converts back C function names/variables names/source locations back to Nelua, but currently this is not planned or being worked on, because most of times debugging in C is enough.
--sanitize
and --gdb
Both options require some support in the environment. --debug
you need to have gdb
installed and ready. --sanitize
your C compiler need to have sanitizer libraries available. This might not be the case in all platforms or compilers. Try using a combination of the options that works for you.
we need nelua debugger(vscode) or tell us how to debug my app?