gpt4 book ai didi

c++ - 如何使用 gdb 从核心文件中获取 lua 堆栈跟踪

转载 作者:IT老高 更新时间:2023-10-28 21:47:13 29 4
gpt4 key购买 nike

我有一个调用 lua 作为脚本语言的 C++ 应用程序(用于 OS X)。我正在运行大量这些应用程序(100 个)并且它们可以运行很长一段时间(几天或几周)。

有时会崩溃。当它崩溃时,它会给我留下一个可爱的核心文件。

我可以在 gdb 中打开这个核心文件并找到应用程序崩溃的位置。我可以遍历调用堆栈并找到一个 lua_State 变量的实例。我的问题是我想看看 lua 调用堆栈是什么样的这次……

请记住,由于这是一个核心,我无权调用 C 函数,这排除了调试 lua 脚本的几种常用方法。

我想避免通过调试钩子(Hook)添加手动跟踪,因为我担心额外的性能损失和增加的复杂性。

如何遍历 lua 内部结构来获取调用堆栈信息?

最佳答案

我创建了一个 GDB 脚本来执行 mac 链接的网页中的内容。它并不漂亮,可能应该被适本地包装到一个函数等中,但这里是为了好奇。

注意:网页上关于 lua 函数的文件名似乎是错误的。在字符串来自 luaL_dofile() 的情况下,文件名以 @ 符号开头。如果它们是从 lua_dostring() 调用的。在这种情况下, $filename 变量被设置为传递给 lua_dostring() 的整个字符串 - 用户可能只对来自的一两行上下文感兴趣那个文件。我不知道如何解决这个问题。

set $p = L->base_ci
while ($p <= L->ci )
if ( $p->func->value.gc->cl.c.isC == 1 )
printf "0x%x C FUNCTION", $p
output $p->func->value.gc->cl.c.f
printf "\n"
else
if ($p->func.tt==6)
set $proto = $p->func->value.gc->cl.l.p
set $filename = (char*)(&($proto->source->tsv) + 1)
set $lineno = $proto->lineinfo[ $p->savedpc - $proto->code -1 ]
printf "0x%x LUA FUNCTION : %d %s\n", $p, $lineno, $filename
else
printf "0x%x LUA BASE\n", $p
end
end
set $p = $p+1
end

这会输出如下内容:

0x1002b0 LUA BASE
0x1002c8 LUA FUNCTION : 4 @a.lua
0x1002e0 LUA FUNCTION : 3 @b.lua
0x100310 C FUNCTION(lua_CFunction) 0x1fda <crash_function(lua_State*)>

当我从这段代码中调试崩溃时:

// This is a file designed to crash horribly when run.
// It should generate a core, and it should crash inside some lua functions

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

#include <iostream>
#include <signal.h>

int crash_function(lua_State * L)
{
raise( SIGABRT ); //This should dump core!
return 0;
}



int main()
{
lua_State * L = luaL_newstate();
lua_pushcfunction(L, crash_function);
lua_setfield(L, LUA_GLOBALSINDEX, "C");

luaopen_base(L);
if( 1 == luaL_dofile(L, "a.lua" ))
{
std::cout<<"ERROR: "<<lua_tostring(L,-1)<<std::endl;
return 1;
}
if( 1 == luaL_dofile(L, "b.lua" ))
{
std::cout<<"ERROR: "<<lua_tostring(L,-1)<<std::endl;
return 1;
}

lua_getfield(L, LUA_GLOBALSINDEX, "A");
lua_pcall(L, 0, 0, NULL);
}

使用 a.lua

-- a.lua
-- just calls B, which calls C which should crash
function A()
B()
end

和 b.lua

-- b.lua
function B()
C()
end

关于c++ - 如何使用 gdb 从核心文件中获取 lua 堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8528503/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com