edubart / nelua-lang

Minimal, efficient, statically-typed and meta-programmable systems programming language heavily inspired by Lua, which compiles to C and native code.
https://nelua.io
MIT License
1.99k stars 64 forks source link

Range check error messages point to library code (point of check) rather than user code (point of error) #242

Closed jrfondren closed 9 months ago

jrfondren commented 9 months ago

Code example

require 'string'

local function has_error()
  local s = 'hello'
  print(s[0])
end

has_error()

Which has this output:

string.nelua:311:16: runtime error: index out of range
  check(i >= 1 and i <= s.size, 'index out of range')
               ^~~~~~~~~~~~~~~

Aborted

Expected behavior

Output similar to the following's:

require 'vector'

local function has_error()
  local s: vector(integer) = {1, 2, 3}
  print(s[-1])
end

has_error()

which is:

arrindex.nelua:1:1: from: AST node Block
require 'vector'
^~~~~~~~~~~~~~~~
arrindex.nelua:4:3: from: AST node Block
  local s: vector(integer) = {1, 2, 3}
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: in call of function 'vector(int64).__atindex' at argument 1: constant value `-1` for type `usize` is out of range, the minimum is `0` and maximum is `18446744073709551615`

NB. s[500] has the first output, rather than this.

Workaround

Running with -S gives more information, if only of C line numbers:

$ nelua -S strindex.nelua
string.nelua:311:16: runtime error: index out of range
  check(i >= 1 and i <= s.size, 'index out of range')
               ^~~~~~~~~~~~~~~

/home/jfondren/.cache/nelua/strindex.c:161:3: runtime error: execution reached an unreachable program point
    #0 0x561a9e518267 in nelua_abort /home/jfondren/.cache/nelua/strindex.c:161
    #1 0x561a9e51872f in nelua_assert_line_1 /home/jfondren/.cache/nelua/strindex.c:169
    #2 0x561a9e518ada in nelua_nlstring___atindex /home/jfondren/.cache/nelua/strindex.c:173
    #3 0x561a9e518ada in strindex_has_error /home/jfondren/.cache/nelua/strindex.c:195
    #4 0x561a9e518c29 in nelua_main /home/jfondren/.cache/nelua/strindex.c:198
    #5 0x561a9e518c50 in main /home/jfondren/.cache/nelua/strindex.c:202
    #6 0x7fba66e461c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #7 0x7fba66e46284 in __libc_start_main_impl ../csu/libc-start.c:360
    #8 0x561a9e518180 in _start (/home/jfondren/.cache/nelua/strindex+0x2180)

Environment

x86_64 linux Nelua 0.2.0-dev Build number: 1609 Git date: 2023-11-15 18:57:47 -0300 Git hash: 19917edbf61fac431256f14682c331d8af1d9f34 Semantic version: 0.2.0-dev.1609+19917edb Copyright (C) 2019-2023 Eduardo Bart (https://nelua.io/)

edubart commented 9 months ago

This is not a bug, while compile time errors can traceback the origin of the error, runtime errors cannot. Runtime asserts and checks will only show the line where the error happened.

There is no good cross platform and lightweight way to perform tracebacks at runtime, the best you can do is to use --sanitize (available only in some systems) so it gives a C traceback of the error. Luckily the C function names are not that hard to understand, and even the C code is not hard to follow when debugging nasty bugs.

I see this as a possible enhancement for the future, that is, to have nice tracebacks messages in case of runtime errors, showing Nelua code, not C code. But it's not that simple to do, and the cross platform way would pollute the C codegen with frame tracing everywhere and also hit performance, I would have to introduce a debug build.