| 831 | return &g_debug_infos; |
| 832 | } |
| 833 | static int enter_lua_debugger(lua_State *L) |
| 834 | { |
| 835 | LuaDebuggerInfoList *debugger_info = get_lua_debugger_info_list_in_state(L); |
| 836 | if (!debugger_info) |
| 837 | return 0; |
| 838 | if (lua_gettop(L) > 0 && lua_isstring(L, 1)) |
| 839 | { |
| 840 | // if has string parameter, use this function to get the value of the name in running debugger; |
| 841 | auto found = debugger_info->find(luaL_checkstring(L, 1)); |
| 842 | if (found == debugger_info->end()) |
| 843 | return 0; |
| 844 | return 0; |
| 845 | } |
| 846 | |
| 847 | debugger_info->clear(); |
| 848 | g_debug_running = true; |
| 849 | |
| 850 | // get all info snapshot in current lua_State stack |
| 851 | // and then pause the thread(but other thread can use this lua_State |
| 852 | // maybe you want to start a REPL before real enter debugger |
| 853 | |
| 854 | // first need back to caller func frame |
| 855 | |
| 856 | CallInfo *ci = L->ci; |
| 857 | auto old_l_top = L->top; |
| 858 | CallInfo *oci = ci->previous; |
| 859 | Proto *np = getproto(ci->func); |
| 860 | Proto *p = getproto(oci->func); |
| 861 | LClosure *ocl = clLvalue(oci->func); |
| 862 | int real_localvars_count = (int)(ci->func - oci->func - 1); |
| 863 | int linedefined = p->linedefined; |
| 864 | // fprintf(L->out, "debugging into line %d\n", linedefined); // FIXME: logging the debugging code line |
| 865 | L->ci = oci; // FIXME: 考虑不直接复制ci,改成类似函数入栈出栈的方式 |
| 866 | int top = lua_gettop(L); |
| 867 | |
| 868 | // capture locals vars and values(need get localvar name from whereelse) |
| 869 | for (int i = 0; i < top; ++i) |
| 870 | { |
| 871 | luaL_tojsonstring(L, i + 1, nullptr); |
| 872 | const char *value_str = luaL_checkstring(L, -1); |
| 873 | lua_pop(L, 1); |
| 874 | // if the debugger position is before the localvar position, ignore the next localvars |
| 875 | if (i >= real_localvars_count) // the localvars is after the debugger() call |
| 876 | break; |
| 877 | // get local var name |
| 878 | if (i < p->sizelocvars) |
| 879 | { |
| 880 | LocVar localvar = p->locvars[i]; |
| 881 | const char *varname = getstr(localvar.varname); |
| 882 | |
| 883 | if (std::string(value_str) != "nil") // 考虑到还没用用到的var也会表现为nil,这里不输出nil值的变量 |
| 884 | { |
| 885 | fprintf(L->out, "[debugger]%s=%s\n", varname, value_str); |
| 886 | } |
| 887 | debugger_info->insert(std::make_pair(varname, std::make_pair(value_str, false))); |
| 888 | if(remote_debugger) |
| 889 | { |
| 890 | remote_debugger->set_last_lvm_debugger_status(varname, value_str, false); |
nothing calls this directly
no test coverage detected