diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-12-14 12:50:05 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-12-14 12:50:05 -0300 |
commit | 066e0f93c4901e601d93e31fb700f8f66f95feb8 (patch) | |
tree | 8b7464bbc4bbe12db97eb34f3b28874caffd1411 /ldebug.c | |
parent | 0bfc572e51d9035a615ef6e9523f736c9ffa8e57 (diff) | |
download | lua-066e0f93c4901e601d93e31fb700f8f66f95feb8.tar.gz lua-066e0f93c4901e601d93e31fb700f8f66f95feb8.tar.bz2 lua-066e0f93c4901e601d93e31fb700f8f66f95feb8.zip |
Fix debug information about finalizers
The flag CIST_FIN does not mark a finalizer, but the function that was
running when the finalizer was called. (So, the function did not call
the finalizer, but it looks that way in the stack.)
Diffstat (limited to 'ldebug.c')
-rw-r--r-- | ldebug.c | 54 |
1 files changed, 31 insertions, 23 deletions
@@ -34,8 +34,8 @@ | |||
34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) | 34 | #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) |
35 | 35 | ||
36 | 36 | ||
37 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | 37 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, |
38 | const char **name); | 38 | const char **name); |
39 | 39 | ||
40 | 40 | ||
41 | static int currentpc (CallInfo *ci) { | 41 | static int currentpc (CallInfo *ci) { |
@@ -317,15 +317,9 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |||
317 | 317 | ||
318 | 318 | ||
319 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | 319 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { |
320 | if (ci == NULL) /* no 'ci'? */ | 320 | /* calling function is a known function? */ |
321 | return NULL; /* no info */ | 321 | if (ci != NULL && !(ci->callstatus & CIST_TAIL)) |
322 | else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ | 322 | return funcnamefromcall(L, ci->previous, name); |
323 | *name = "__gc"; | ||
324 | return "metamethod"; /* report it as such */ | ||
325 | } | ||
326 | /* calling function is a known Lua function? */ | ||
327 | else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) | ||
328 | return funcnamefromcode(L, ci->previous, name); | ||
329 | else return NULL; /* no way to find a name */ | 323 | else return NULL; /* no way to find a name */ |
330 | } | 324 | } |
331 | 325 | ||
@@ -597,16 +591,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
597 | ** Returns what the name is (e.g., "for iterator", "method", | 591 | ** Returns what the name is (e.g., "for iterator", "method", |
598 | ** "metamethod") and sets '*name' to point to the name. | 592 | ** "metamethod") and sets '*name' to point to the name. |
599 | */ | 593 | */ |
600 | static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | 594 | static const char *funcnamefromcode (lua_State *L, const Proto *p, |
601 | const char **name) { | 595 | int pc, const char **name) { |
602 | TMS tm = (TMS)0; /* (initial value avoids warnings) */ | 596 | TMS tm = (TMS)0; /* (initial value avoids warnings) */ |
603 | const Proto *p = ci_func(ci)->p; /* calling function */ | ||
604 | int pc = currentpc(ci); /* calling instruction index */ | ||
605 | Instruction i = p->code[pc]; /* calling instruction */ | 597 | Instruction i = p->code[pc]; /* calling instruction */ |
606 | if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ | ||
607 | *name = "?"; | ||
608 | return "hook"; | ||
609 | } | ||
610 | switch (GET_OPCODE(i)) { | 598 | switch (GET_OPCODE(i)) { |
611 | case OP_CALL: | 599 | case OP_CALL: |
612 | case OP_TAILCALL: | 600 | case OP_TAILCALL: |
@@ -643,6 +631,26 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci, | |||
643 | return "metamethod"; | 631 | return "metamethod"; |
644 | } | 632 | } |
645 | 633 | ||
634 | |||
635 | /* | ||
636 | ** Try to find a name for a function based on how it was called. | ||
637 | */ | ||
638 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, | ||
639 | const char **name) { | ||
640 | if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ | ||
641 | *name = "?"; | ||
642 | return "hook"; | ||
643 | } | ||
644 | else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */ | ||
645 | *name = "__gc"; | ||
646 | return "metamethod"; /* report it as such */ | ||
647 | } | ||
648 | else if (isLua(ci)) | ||
649 | return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name); | ||
650 | else | ||
651 | return NULL; | ||
652 | } | ||
653 | |||
646 | /* }====================================================== */ | 654 | /* }====================================================== */ |
647 | 655 | ||
648 | 656 | ||
@@ -728,14 +736,14 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | |||
728 | 736 | ||
729 | 737 | ||
730 | /* | 738 | /* |
731 | ** Raise an error for calling a non-callable object. Try to find | 739 | ** Raise an error for calling a non-callable object. Try to find a name |
732 | ** a name for the object based on the code that made the call | 740 | ** for the object based on how it was called ('funcnamefromcall'); if it |
733 | ** ('funcnamefromcode'); if it cannot get a name there, try 'varinfo'. | 741 | ** cannot get a name there, try 'varinfo'. |
734 | */ | 742 | */ |
735 | l_noret luaG_callerror (lua_State *L, const TValue *o) { | 743 | l_noret luaG_callerror (lua_State *L, const TValue *o) { |
736 | CallInfo *ci = L->ci; | 744 | CallInfo *ci = L->ci; |
737 | const char *name = NULL; /* to avoid warnings */ | 745 | const char *name = NULL; /* to avoid warnings */ |
738 | const char *kind = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL; | 746 | const char *kind = funcnamefromcall(L, ci, &name); |
739 | const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o); | 747 | const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o); |
740 | typeerror(L, o, "call", extra); | 748 | typeerror(L, o, "call", extra); |
741 | } | 749 | } |