Low-level access to the innards

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Low-level access to the innards

Eduardo Ochs
Hi list,

I have a handful of (related) questions that I've been postponing
asking at the list for months, or maybe years - because I was
afraid that the main answers were going to be "why do you want
this?" and "what you want is wrong".

The real "why" would take pages - and probably also a couple of
videos to show how, in certain very specific contexts, it does
make sense to send some very long commands to GDB - commands that
would then be _readable_ by low-level-minded humans, but that
would not be _written_ by hand (often). So let me leave
these "why"s to be answered later - I am preparing one of the
said videos, by the way -, and let me try to disguise a few of my
questions as challenges to people who know Lua's innards quite
well. Here they are.


The challenge
=============
Suppose that we've set a breakpoint in math_sin, and then we ran
this Lua code:

  outer_fun = function (a, b)
      local c, d, e = "CC", "DD", "EE"
      return 1 + inner_fun("FF", "GG")
    end

  inner_fun = function (f, g)
      local h, i, j = "HH", "II", "JJ"
      return math.sin(0)
    end

  twentytwo = "22"
  twentytwon = 22
  outer_fun("AA", "BB")

So now we are at the GDB prompt, in math_sin, i.e., in


and thus we have access to a variable L ("lua_State *L"), and we
know that GDB can call functions and has _some_ support for C
macros, but it feels happier when it just has to deal with
low-level expressions like:

  L->top[-1].value.gc.ts.tsv.hash

So, it _must_ be possible to start from just L - plus the hash
values for the strings "twentytwo", "twentytwon", "a", "b",
..., "j" - and then, through a contorted series of array and
field accesses, reach the positions in the memory where are
stored:

  1) the value of the variable "twentytwo" (as a string),
  2) the value of the variable "twentytwon" (as a number),
  3) the name of the variable "twentytwo" (as a string),
  4) the value of the parameter "g" of inner_fun,
  5) the name - "g" - of the second parameter of inner_fun,
  6) the value of the local variable "e" of outer_fun,
  7) the name of the local variable "e" of outer_fun.


On style
========
Think that your expressions will be used to explain the data
structures of Lua - more precisely, "PUC-Lua" - in _just_ the
sample case above - the reader is expected to be able to
generalize by himself. So: start from L, and use
just "->"s, "."s, "*"s, and "[n]"s with explicit "n"s. Don't be
afraid to use magic numbers in the "[n]"s - though explanations
like "we can calculate that n by using the function call
such-and-such" are welcome...

Note that such low-level answers are far from useless - they are
"canonical" in a precise sense (that I am not going to formalize
now =)), and they are very easy to _test_ and to _annotate_ -
e.g., "this sequence of four field accesses here correspond to
the effect of macro `blah', these others here to the function
call `bletch'" - and they can sort of complement texts like:



  Cheers =),
    Eduardo Ochs

Reply | Threaded
Open this post in threaded view
|

RE: Low-level access to the innards

Dan Tull
> Suppose that we've set a breakpoint in math_sin, and then we ran
> this Lua code:

  outer_fun = function (a, b)
      local c, d, e = "CC", "DD", "EE"
      return 1 + inner_fun("FF", "GG")
    end

  inner_fun = function (f, g)
      local h, i, j = "HH", "II", "JJ"
      return math.sin(0)
    end

  twentytwo = "22"
  twentytwon = 22
  outer_fun("AA", "BB")

> So now we are at the GDB prompt, in math_sin ...
> So, it _must_ be possible to start from just L ...through
> a contorted series of array and field accesses...

>  1) the value of the variable "twentytwo" (as a string),
>  2) the value of the variable "twentytwon" (as a number),
>  3) the name of the variable "twentytwo" (as a string),
>  4) the value of the parameter "g" of inner_fun,
>  5) the name - "g" - of the second parameter of inner_fun,
>  6) the value of the local variable "e" of outer_fun,
>  7) the name of the local variable "e" of outer_fun.

I've been known to do things of this sort in gdb/lldb. The same
techniques are also useful in WinDbg for doing post mortem on
a full memory dump of a crashed or hung process.

I even had a (really, really, ugly) blob of WinDbg hackery
that would dump out the Lua call stack at a particular point*
so I could track down a tricky hang.

> Think that your expressions will be used to explain the data
> structures of Lua...and they can sort of complement texts like:
>
> http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf
> http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/jucs05.pdf

So are you writing such a doc and using this post as a means
to crowd source some of the content?

I can't help but feel I'm being tricked into doing somebody
else's homework... ;o)

On a related note, I've considered composing a series of gdb/lldb
console or Visual Studio immediate window macros* to make it
easier to access certain commonly interesting pieces of Lua state
information in a native debugger, which entails a similar enumeration
and generalization of recipes for such internal access.

Which is as good a time as any to ask: has somebody else already done
and shared such a thing? (I wouldn't want to duplicate effort)

Dan Tull
Lua Tools Dev
Adobe

* Note I've seen such things done by calling functions, but often they
result in crashing the app in the debugger due to using the Lua state
while it is potentially in the middle of doing something else. My method
was directly reading the structures to avoid bad side effects. Also, you
it works on a memory dump where you can't call functions.

Looks like I'm not alone:
http://zeuxcg.org/2010/11/07/lua-callstack-with-c-debugger/

Reply | Threaded
Open this post in threaded view
|

Re: Low-level access to the innards

Michal Kottman-2
On 9 January 2013 21:22, Dan Tull <[hidden email]> wrote:
Which is as good a time as any to ask: has somebody else already done
and shared such a thing? (I wouldn't want to duplicate effort)

Maybe not directly to-the-point, but I have written some GDB helper macros [1] which allow you to pretty-print Lua tables and show the values on the Lua stack by accessing the internals, and call Lua debug.traceback (only works during live debugging). 

Reply | Threaded
Open this post in threaded view
|

RE: Low-level access to the innards

Dan Tull
> > On 9 January 2013 21:22, Dan Tull <[hidden email]<mailto:[hidden email]>> wrote:
> > Which is as good a time as any to ask: has somebody else already done
> > and shared such a thing? (I wouldn't want to duplicate effort)

> (Michal Kottman [[hidden email]])
>
> I have written some GDB helper macros [1] which allow you to pretty-print
> Lua tables and show the values on the Lua stack by accessing the internals,
> and call Lua debug.traceback (only works during live debugging).
>
> [1] https://github.com/mkottman/lua-gdb-helper

That does look like what I had in mind. I'll have to give it a spin.

Thanks -- DT