2

I have a Lua file (too old to remember what I did exactly) that includes this line:

local arg_cnt = debug.getinfo(formatter).nparams

which triggers an error with the message

attempt to index a boolean value (global 'debug')

debug is a Lua table with introspection functions, which I obviously wanted to use, and which has to have worked when I wrote the code maybe one or two years ago.

How can I determine why this doesn't work anymore?

My initial suspicion in that type of cases is that debug is overwritten at some point, but all kind of searching and grepping doesn't point me to a place where that might happen.

Is it possible that there have been changes to the core so I have to explicitly activate the debug table? I'm on the current Ubuntu version's repository version with

lualatex --version
This is LuaHBTeX, Version 1.12.0 (TeX Live 2020/Debian)
4
  • I have the library, when I do \directlua{print(debug)} in a small latex or plain document I get a table. Nov 17, 2020 at 16:21
  • OK, I can confirm this. This means somewhere in either my infrastructure or a buggy package the table is overwritten with a boolean. What way could this happen except thtrough debug = for which I can grep?
    – uli_1973
    Nov 17, 2020 at 17:29
  • 1
    just stick \directlua{print(debug)} on every other line of your preamble, see where it changes? Nov 17, 2020 at 18:46
  • Thank you for the idea. Fortunately my preamble is very modular, so I could circle in in a "bisect" way. It turns out I had already fixed this exact problem last year in github.com/micoloretan/selnolig/pull/10, but unfortunately it hasn't been pushed to CTAN yet.
    – uli_1973
    Nov 18, 2020 at 4:29

2 Answers 2

2

When trying to find out who is responsible for changing global variables in Lua, it is sometimes useful to temporarily assign a metatable to the global table. (I strongly recommend never to do this outside of debugging and to let the metatable work as close to a normal tableas possible, otherwise you get all kinds of weird behavior.)

So, in order to detect changes to the global debug through metamethods, you have to delete the debug table. You can virtually put it back though the __index metamethod. Then you can use __newindex to detect attempts create a new global debug in which case you can print a warning, using the original debug table to get information about the responsible Lua function. In isn't that helpful though if it was reset e.g. in \directlua, but you can use LuaTeX's status table to additionally provide the current TeX file and line.

Of yourse you have to do this before loading anything which might be responsble, do it's best to put it even before \documentclass:

\directlua{
  local debug = debug
  local traceback, getinfo = debug.traceback, debug.getinfo
  _G.debug = nil
  setmetatable(_G, {
    __index = {debug = debug},
    __newindex = function(t, k, v)
      if k == "debug" then
        local guilty = getinfo(2)
        texio.write_nl("We found the naughty party: " .. (guilty.name or "nameless devil") .. " in " .. guilty.source .. " at line " .. guilty.currentline)
        texio.write_nl("TeX is currently reading " .. status.filename .. " at line " .. status.linenumber)
      end
      return rawset(t, k, v)
    end,
  })
}
\documentclass{article}
\usepackage{grandmother}
\begin{document}
\end{document}

which would e.g. provide the output

...
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/size10.clo))
(./grandmother.sty
We found the naughty party: rose_tylor in @./bad_wolf.lua at line 2
TeX is currently reading ./grandmother.sty at line 4)
(/usr/local/texlive/2020/texmf-dist/tex/latex/l3backend/l3backend-luatex.def)
...

indicating that a function rose_tylor in the file ./bad_wolf.lua is changing debug, the change happens in line 2 of the file and it is loaded in grandmother.sty on line 4.

1

This is not a concrete answer to the question, but I'd like to write a generic answer anyway.

attempt to index a boolean value (global 'debug')

is a Lua error message which tells you that you are attempting to use a member of a Lua table, but what you treat as a table is not a table (anymore).

In my case I tried to call the function getinfo() from the table debug (which is built into Lua and should be available anywhere), but when invoking it Lua found a boolean value (true or false) instead.

It is very likely that this observation indicates that the builtin table debug has at some point been overwritten with a boolean, either in your preamble or - as a bug - in a package.

To find the culprit it is useful to insert

\directlua{print(debug)}
\directlua{debug.go}

in your preamble as suggested in this comment. The first line will print the table address - as long as there still is a table - the second line will cause an error and stop the compilation. You can iterate through every step of your preamble to find exactly where the problem starts.

Underlying problem

The reason for this issue is a typical Lua programming error, in this case in a package. In order to create a status flag the package contained the line

debug = false

setting the debug variable to false as its default value, which is then used in a function outputting debug information.

The problem is that in Lua variables are by default in the global namespace (opposite behaviour from e.g. Python) - which means that the line above overwrites the global variable and effectively "kills" the whole builtin Lua table.

This is a very good example for the advice never to forget using local variables in Lua wherever possible:

local debug = false

This way debug is local to the current module and does not affect the global table with the same name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.