2 ** Debugging and introspection.
3 ** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
21 /* -- Frames -------------------------------------------------------------- */
23 /* Get frame corresponding to a level. */
24 cTValue
*lj_debug_frame(lua_State
*L
, int level
, int *size
)
26 cTValue
*frame
, *nextframe
, *bot
= tvref(L
->stack
);
27 /* Traverse frames backwards. */
28 for (nextframe
= frame
= L
->base
-1; frame
> bot
; ) {
29 if (frame_gc(frame
) == obj2gco(L
))
30 level
++; /* Skip dummy frames. See lj_meta_call(). */
32 *size
= (int)(nextframe
- frame
);
33 return frame
; /* Level found. */
36 if (frame_islua(frame
)) {
37 frame
= frame_prevl(frame
);
39 if (frame_isvarg(frame
))
40 level
++; /* Skip vararg pseudo-frame. */
41 frame
= frame_prevd(frame
);
45 return NULL
; /* Level not found. */
48 /* Invalid bytecode position. */
49 #define NO_BCPOS (~(BCPos)0)
51 /* Return bytecode position for function/frame or NO_BCPOS. */
52 static BCPos
debug_framepc(lua_State
*L
, GCfunc
*fn
, cTValue
*nextframe
)
57 lua_assert(fn
->c
.gct
== ~LJ_TFUNC
|| fn
->c
.gct
== ~LJ_TTHREAD
);
58 if (!isluafunc(fn
)) { /* Cannot derive a PC for non-Lua functions. */
60 } else if (nextframe
== NULL
) { /* Lua function on top. */
61 void *cf
= cframe_raw(L
->cframe
);
62 if (cf
== NULL
|| (char *)cframe_pc(cf
) == (char *)cframe_L(cf
))
64 ins
= cframe_pc(cf
); /* Only happens during error/hook handling. */
66 if (frame_islua(nextframe
)) {
67 ins
= frame_pc(nextframe
);
68 } else if (frame_iscont(nextframe
)) {
69 ins
= frame_contpc(nextframe
);
71 /* Lua function below errfunc/gc/hook: find cframe to get the PC. */
72 void *cf
= cframe_raw(L
->cframe
);
73 TValue
*f
= L
->base
-1;
76 while (f
> nextframe
) {
81 cf
= cframe_raw(cframe_prev(cf
));
86 cf
= cframe_raw(cframe_prev(cf
));
91 pos
= proto_bcpos(pt
, ins
) - 1;
93 if (pos
> pt
->sizebc
) { /* Undo the effects of lj_trace_exit for JLOOP. */
94 GCtrace
*T
= (GCtrace
*)((char *)(ins
-1) - offsetof(GCtrace
, startins
));
95 lua_assert(bc_isret(bc_op(ins
[-1])));
96 pos
= proto_bcpos(pt
, mref(T
->startpc
, const BCIns
));
102 /* -- Line numbers -------------------------------------------------------- */
104 /* Get line number for a bytecode position. */
105 BCLine LJ_FASTCALL
lj_debug_line(GCproto
*pt
, BCPos pc
)
107 const void *lineinfo
= proto_lineinfo(pt
);
108 if (pc
<= pt
->sizebc
&& lineinfo
) {
109 BCLine first
= pt
->firstline
;
110 if (pc
== pt
->sizebc
) return first
+ pt
->numline
;
111 if (pc
-- == 0) return first
;
112 if (pt
->numline
< 256)
113 return first
+ (BCLine
)((const uint8_t *)lineinfo
)[pc
];
114 else if (pt
->numline
< 65536)
115 return first
+ (BCLine
)((const uint16_t *)lineinfo
)[pc
];
117 return first
+ (BCLine
)((const uint32_t *)lineinfo
)[pc
];
122 /* Get line number for function/frame. */
123 static BCLine
debug_frameline(lua_State
*L
, GCfunc
*fn
, cTValue
*nextframe
)
125 BCPos pc
= debug_framepc(L
, fn
, nextframe
);
126 if (pc
!= NO_BCPOS
) {
127 GCproto
*pt
= funcproto(fn
);
128 lua_assert(pc
<= pt
->sizebc
);
129 return lj_debug_line(pt
, pc
);
134 /* -- Variable names ------------------------------------------------------ */
136 /* Read ULEB128 value. */
137 static uint32_t debug_read_uleb128(const uint8_t **pp
)
139 const uint8_t *p
= *pp
;
141 if (LJ_UNLIKELY(v
>= 0x80)) {
144 do { v
|= ((*p
& 0x7f) << (sh
+= 7)); } while (*p
++ >= 0x80);
150 /* Get name of a local variable from slot number and PC. */
151 static const char *debug_varname(const GCproto
*pt
, BCPos pc
, BCReg slot
)
153 const uint8_t *p
= proto_varinfo(pt
);
157 const char *name
= (const char *)p
;
159 BCPos startpc
, endpc
;
160 if (vn
< VARNAME__MAX
) {
161 if (vn
== VARNAME_END
) break; /* End of varinfo. */
163 while (*p
++) ; /* Skip over variable name string. */
165 lastpc
= startpc
= lastpc
+ debug_read_uleb128(&p
);
166 if (startpc
> pc
) break;
167 endpc
= startpc
+ debug_read_uleb128(&p
);
168 if (pc
< endpc
&& slot
-- == 0) {
169 if (vn
< VARNAME__MAX
) {
170 #define VARNAMESTR(name, str) str "\0"
171 name
= VARNAMEDEF(VARNAMESTR
);
173 if (--vn
) while (*name
++ || --vn
) ;
182 /* Get name of local variable from 1-based slot number and function/frame. */
183 static TValue
*debug_localname(lua_State
*L
, const lua_Debug
*ar
,
184 const char **name
, BCReg slot1
)
186 uint32_t offset
= (uint32_t)ar
->i_ci
& 0xffff;
187 uint32_t size
= (uint32_t)ar
->i_ci
>> 16;
188 TValue
*frame
= tvref(L
->stack
) + offset
;
189 TValue
*nextframe
= size
? frame
+ size
: NULL
;
190 GCfunc
*fn
= frame_func(frame
);
191 BCPos pc
= debug_framepc(L
, fn
, nextframe
);
192 if (pc
!= NO_BCPOS
&&
193 (*name
= debug_varname(funcproto(fn
), pc
, slot1
-1)) != NULL
)
195 else if (slot1
> 0 && frame
+ slot1
< (nextframe
? nextframe
: L
->top
))
196 *name
= "(*temporary)";
202 /* Get name of upvalue. */
203 const char *lj_debug_uvname(GCproto
*pt
, uint32_t idx
)
205 const uint8_t *p
= proto_uvinfo(pt
);
206 lua_assert(idx
< pt
->sizeuv
);
208 if (idx
) while (*p
++ || --idx
) ;
209 return (const char *)p
;
212 /* Get name and value of upvalue. */
213 const char *lj_debug_uvnamev(cTValue
*o
, uint32_t idx
, TValue
**tvp
)
216 GCfunc
*fn
= funcV(o
);
218 GCproto
*pt
= funcproto(fn
);
219 if (idx
< pt
->sizeuv
) {
220 *tvp
= uvval(&gcref(fn
->l
.uvptr
[idx
])->uv
);
221 return lj_debug_uvname(pt
, idx
);
224 if (idx
< fn
->c
.nupvalues
) {
225 *tvp
= &fn
->c
.upvalue
[idx
];
233 /* Deduce name of an object from slot number and PC. */
234 const char *lj_debug_slotname(GCproto
*pt
, const BCIns
*ip
, BCReg slot
,
239 lname
= debug_varname(pt
, proto_bcpos(pt
, ip
), slot
);
240 if (lname
!= NULL
) { *name
= lname
; return "local"; }
241 while (--ip
> proto_bc(pt
)) {
243 BCOp op
= bc_op(ins
);
244 BCReg ra
= bc_a(ins
);
245 if (bcmode_a(op
) == BCMbase
) {
246 if (slot
>= ra
&& (op
!= BC_KNIL
|| slot
<= bc_d(ins
)))
248 } else if (bcmode_a(op
) == BCMdst
&& ra
== slot
) {
249 switch (bc_op(ins
)) {
251 if (ra
== slot
) { slot
= bc_d(ins
); goto restart
; }
254 *name
= strdata(gco2str(proto_kgc(pt
, ~(ptrdiff_t)bc_d(ins
))));
257 *name
= strdata(gco2str(proto_kgc(pt
, ~(ptrdiff_t)bc_c(ins
))));
258 if (ip
> proto_bc(pt
)) {
260 if (bc_op(insp
) == BC_MOV
&& bc_a(insp
) == ra
+1 &&
261 bc_d(insp
) == bc_b(ins
))
266 *name
= lj_debug_uvname(pt
, bc_d(ins
));
276 /* Deduce function name from caller of a frame. */
277 const char *lj_debug_funcname(lua_State
*L
, TValue
*frame
, const char **name
)
282 if (frame
<= tvref(L
->stack
))
284 if (frame_isvarg(frame
))
285 frame
= frame_prevd(frame
);
286 pframe
= frame_prev(frame
);
287 fn
= frame_func(pframe
);
288 pc
= debug_framepc(L
, fn
, frame
);
289 if (pc
!= NO_BCPOS
) {
290 GCproto
*pt
= funcproto(fn
);
291 const BCIns
*ip
= &proto_bc(pt
)[check_exp(pc
< pt
->sizebc
, pc
)];
292 MMS mm
= bcmode_mm(bc_op(*ip
));
294 BCReg slot
= bc_a(*ip
);
295 if (bc_op(*ip
) == BC_ITERC
) slot
-= 3;
296 return lj_debug_slotname(pt
, ip
, slot
, name
);
297 } else if (mm
!= MM__MAX
) {
298 *name
= strdata(mmname_str(G(L
), mm
));
305 /* -- Source code locations ----------------------------------------------- */
307 /* Generate shortened source name. */
308 void lj_debug_shortname(char *out
, GCstr
*str
)
310 const char *src
= strdata(str
);
312 strncpy(out
, src
+1, LUA_IDSIZE
); /* Remove first char. */
313 out
[LUA_IDSIZE
-1] = '\0'; /* Ensures null termination. */
314 } else if (*src
== '@') { /* Output "source", or "...source". */
315 size_t len
= str
->len
-1;
316 src
++; /* Skip the `@' */
317 if (len
>= LUA_IDSIZE
) {
318 src
+= len
-(LUA_IDSIZE
-4); /* Get last part of file name. */
319 *out
++ = '.'; *out
++ = '.'; *out
++ = '.';
322 } else { /* Output [string "string"]. */
323 size_t len
; /* Length, up to first control char. */
324 for (len
= 0; len
< LUA_IDSIZE
-12; len
++)
325 if (((const unsigned char *)src
)[len
] < ' ') break;
326 strcpy(out
, "[string \""); out
+= 9;
327 if (src
[len
] != '\0') { /* Must truncate? */
328 if (len
> LUA_IDSIZE
-15) len
= LUA_IDSIZE
-15;
329 strncpy(out
, src
, len
); out
+= len
;
330 strcpy(out
, "..."); out
+= 3;
332 strcpy(out
, src
); out
+= len
;
338 /* Add current location of a frame to error message. */
339 void lj_debug_addloc(lua_State
*L
, const char *msg
,
340 cTValue
*frame
, cTValue
*nextframe
)
343 GCfunc
*fn
= frame_func(frame
);
345 BCLine line
= debug_frameline(L
, fn
, nextframe
);
347 char buf
[LUA_IDSIZE
];
348 lj_debug_shortname(buf
, proto_chunkname(funcproto(fn
)));
349 lj_str_pushf(L
, "%s:%d: %s", buf
, line
, msg
);
354 lj_str_pushf(L
, "%s", msg
);
357 /* Push location string for a bytecode position to Lua stack. */
358 void lj_debug_pushloc(lua_State
*L
, GCproto
*pt
, BCPos pc
)
360 GCstr
*name
= proto_chunkname(pt
);
361 const char *s
= strdata(name
);
362 MSize i
, len
= name
->len
;
363 BCLine line
= lj_debug_line(pt
, pc
);
366 for (i
= len
; i
> 0; i
--)
367 if (s
[i
] == '/' || s
[i
] == '\\') {
371 lj_str_pushf(L
, "%s:%d", s
, line
);
372 } else if (len
> 40) {
373 lj_str_pushf(L
, "%p:%d", pt
, line
);
374 } else if (*s
== '=') {
375 lj_str_pushf(L
, "%s:%d", s
+1, line
);
377 lj_str_pushf(L
, "\"%s\":%d", s
, line
);
381 /* -- Public debug API ---------------------------------------------------- */
383 /* lua_getupvalue() and lua_setupvalue() are in lj_api.c. */
385 LUA_API
const char *lua_getlocal(lua_State
*L
, const lua_Debug
*ar
, int n
)
388 TValue
*o
= debug_localname(L
, ar
, &name
, (BCReg
)n
);
390 copyTV(L
, L
->top
, o
);
396 LUA_API
const char *lua_setlocal(lua_State
*L
, const lua_Debug
*ar
, int n
)
399 TValue
*o
= debug_localname(L
, ar
, &name
, (BCReg
)n
);
401 copyTV(L
, o
, L
->top
-1);
406 LUA_API
int lua_getinfo(lua_State
*L
, const char *what
, lua_Debug
*ar
)
409 TValue
*frame
= NULL
;
410 TValue
*nextframe
= NULL
;
413 TValue
*func
= L
->top
- 1;
414 api_check(L
, tvisfunc(func
));
419 uint32_t offset
= (uint32_t)ar
->i_ci
& 0xffff;
420 uint32_t size
= (uint32_t)ar
->i_ci
>> 16;
421 lua_assert(offset
!= 0);
422 frame
= tvref(L
->stack
) + offset
;
423 if (size
) nextframe
= frame
+ size
;
424 lua_assert(frame
<= tvref(L
->maxstack
) &&
425 (!nextframe
|| nextframe
<= tvref(L
->maxstack
)));
426 fn
= frame_func(frame
);
427 lua_assert(fn
->c
.gct
== ~LJ_TFUNC
);
429 for (; *what
; what
++) {
432 GCproto
*pt
= funcproto(fn
);
433 BCLine firstline
= pt
->firstline
;
434 GCstr
*name
= proto_chunkname(pt
);
435 ar
->source
= strdata(name
);
436 lj_debug_shortname(ar
->short_src
, name
);
437 ar
->linedefined
= (int)firstline
;
438 ar
->lastlinedefined
= (int)(firstline
+ pt
->numline
);
439 ar
->what
= firstline
? "Lua" : "main";
442 ar
->short_src
[0] = '[';
443 ar
->short_src
[1] = 'C';
444 ar
->short_src
[2] = ']';
445 ar
->short_src
[3] = '\0';
446 ar
->linedefined
= -1;
447 ar
->lastlinedefined
= -1;
450 } else if (*what
== 'l') {
451 ar
->currentline
= frame
? debug_frameline(L
, fn
, nextframe
) : -1;
452 } else if (*what
== 'u') {
453 ar
->nups
= fn
->c
.nupvalues
;
454 } else if (*what
== 'n') {
455 ar
->namewhat
= frame
? lj_debug_funcname(L
, frame
, &ar
->name
) : NULL
;
456 if (ar
->namewhat
== NULL
) {
460 } else if (*what
== 'f') {
461 setfuncV(L
, L
->top
, fn
);
463 } else if (*what
== 'L') {
465 GCtab
*t
= lj_tab_new(L
, 0, 0);
466 GCproto
*pt
= funcproto(fn
);
467 const void *lineinfo
= proto_lineinfo(pt
);
469 BCLine first
= pt
->firstline
;
470 int sz
= pt
->numline
< 256 ? 1 : pt
->numline
< 65536 ? 2 : 4;
471 MSize i
, szl
= pt
->sizebc
-1;
472 for (i
= 0; i
< szl
; i
++) {
473 BCLine line
= first
+
474 (sz
== 1 ? (BCLine
)((const uint8_t *)lineinfo
)[i
] :
475 sz
== 2 ? (BCLine
)((const uint16_t *)lineinfo
)[i
] :
476 (BCLine
)((const uint32_t *)lineinfo
)[i
]);
477 setboolV(lj_tab_setint(L
, t
, line
), 1);
480 settabV(L
, L
->top
, t
);
486 status
= 0; /* Bad option. */
492 LUA_API
int lua_getstack(lua_State
*L
, int level
, lua_Debug
*ar
)
495 cTValue
*frame
= lj_debug_frame(L
, level
, &size
);
497 ar
->i_ci
= (size
<< 16) + (int)(frame
- tvref(L
->stack
));
500 ar
->i_ci
= level
- size
;