[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: debug.traceback() level handling
- From: William Ahern <william@...>
- Date: Fri, 18 Nov 2022 16:44:36 -0800
On Fri, Nov 18, 2022 at 02:58:30PM +0600, Alexander Chernoskutov wrote:
> Just wanted to confirm, is this report has been registered as an issue?
>
> Can confirm the problem exists.
Maybe a problem, but it's not a bug. See below.
<snip>
> > function foo()
> > print(debug.traceback('hi from traceback', 2)) -- level 2, hide
> > foo()
> > error('hi from error', 2)
> > end
> >
> > function bar()
> > foo()
> > end
> >
> > bar()
> >
> > -->
> >
> > $ lua traceback.lua
> > hi from traceback
> > stack traceback:
> > traceback.lua:8: in function 'bar'
> > traceback.lua:11: in main chunk
> > [C]: in ?
> > lua: traceback.lua:8: hi from error
This is the message generated by the error function, and it's working as
expected, indicating the call site in bar, not foo.
> > stack traceback:
> > [C]: in function 'error'
> > traceback.lua:4: in function 'foo'
> > traceback.lua:8: in function 'bar'
> > traceback.lua:11: in main chunk
> > [C]: in ?
This message isn't generated by error; it's generated by the message handler
to a protected call--e.g. the msgh function argument to xpcall. That message
handler is itself invoking debug.traceback. In Lua code it could even *be*
debug.traceback, as the semantics of xpcall and debug.traceback seem to be
deliberately aligned. But in this case what's happening is the lua command
interpreter's error handler is calling luaL_traceback with a level of 1,
which happens (presumably not coincidentally) to be the default level for
debug.traceback. (See msghandler in src/lua.c.)
In order to get your desired behavior you'd would have to do one of two
things.
1) Modify the lua command-line utility's message handler to magically skip a
level if it recognizes the top of stack as the built-in error function. But
then somebody doing `xpcall(bar, debug.traceback)' wouldn't get the same
behavior, and now everybody will wonder why doing the obvious thing in Lua
or their own Lua C code results in a different message than the lua
command interpreter.
2) Modify luaL_traceback itself to automagically skip a level if it
recognizes the error function. But that's some ugly chumminess between two
distinct functions, *and* you'd need a way to disable it otherwise it could
become very difficult to use debug.traceback (or more specifically
luaL_traceback) to identify bugs at their call site. But you can't magically
overload the level argument; level 0 already has a well-defined and
important meaning useful for inspecting other threads or when the top of
stack is a C function.
The current behavior of luaL_traceback seems perfectly sane and even
necessary so that people are able to fully inspect the stack, yet can still
use these low-level interfaces to build wrappers that implement their
preferred behavior. And changing the lua command-line utility would result
in surprisingly different behavior between the error message printed by a
simple command script, and the error message returned by xpcall(bar,
debug.traceback) or similar C API code.
Is it worth all this additional complexity merely for an aesthetic change?
Many times I've wished for this behavior, too, but as a purely aesthetic
thing it never warranted my time (to e.g. implement a fancier exception
handler), in part because once you go down that road you tend to burn alot
of time--aesthetic desires are insatiable.