lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.