我维护一个小的 C 工具 fleetcfg,它加载一个返回主机列表的 Lua 配置,把它们复制进 HostList,然后打印出来。TCP 探测还是 TODO。
有两个现象,我不确定它们有没有关系。
用真实的 200 台主机的生产配置时,最后列表里有几行名字为空,或者是奇怪的字节。3 台主机的测试配置从没出过这个问题。我怀疑是 Lua 那边,可能是 luaL_dofile 在栈上留下了什么。lua_gc 那个调用我基本排除了,因为加它之前输出就是对的。这一点还没确认。
用 LD_PRELOAD 包装让 malloc/realloc 在第 N 次调用后失败,hostlist_push 里失败时会按设计打印 "out of memory" 并以 1 退出。但 valgrind 报 "definitely lost",而且这块随主机数增长。我以为是 Lua 的清理漏了什么,剩下的由 hostlist_free 兜底。
valgrind --leak-check=full ./fleetcfg $PWD/prod hosts.lua
我的 checkout 路径里有个空格,valgrind 的输出在我看来有点怪。
相关片段如下。
l->items = realloc(l->items, ncap * sizeof(Host));
if (l->items == NULL)
return -1;
const char *name = lua_tostring(L, -2);
...
lua_pop(L, 3);
...
hostlist_push(out, name, port)
你们会从哪里开始查?我不敢保证这两个是分开的,而且我还没在调试器里跑过任何东西。
从英语翻译·查看原文I maintain a small C tool, fleetcfg, that loads a Lua config returning a list of hosts, copies them into a HostList, then prints them. The TCP probe is still a TODO.
Two observations, and I can't tell if they're related:
With the real 200-host prod config, a few lines in the final listing show an empty name or odd bytes. The 3-host test config never does. I suspect the Lua side, maybe what luaL_dofile leaves on the stack. I've pretty much ruled out the lua_gc call, since the output was right before I added it. That is not confirmed.
With an LD_PRELOAD wrapper that fails malloc/realloc after N calls, a failure inside hostlist_push prints "out of memory" and exits 1 as designed. But valgrind reports "definitely lost", and the block grows with the host count. I assumed the Lua cleanup misses something and that hostlist_free covers the rest.
valgrind --leak-check=full ./fleetcfg $PWD/prod hosts.lua
My checkout path has a space in it, and the valgrind output looked odd to me.
Relevant pieces:
l->items = realloc(l->items, ncap * sizeof(Host));
if (l->items == NULL)
return -1;
const char *name = lua_tostring(L, -2);
...
lua_pop(L, 3);
...
hostlist_push(out, name, port)
Where would you start looking? I can't promise the two are separate, and I haven't run anything under a debugger yet.