Lua 설정 파일을 불러와서 호스트 목록을 받고, 그걸 HostList에 복사한 다음 출력하는 작은 C 툴 fleetcfg를 관리하고 있어요. TCP probe는 아직 TODO예요.
관찰한 게 두 가지인데, 서로 관련이 있는지 모르겠어요:
실제 prod 설정(호스트 200개)으로 돌리면 최종 목록에서 몇 줄은 이름이 비어 있거나 이상한 바이트가 찍혀요. 호스트 3개짜리 테스트 설정에서는 한 번도 안 그래요. Lua 쪽이 의심스러운데, luaL_dofile이 스택에 남기는 것 때문일 수도 있어요. lua_gc 호출은 거의 배제했어요. 그걸 넣기 전에도 출력이 맞았거든요. 확실히 확인한 건 아니에요.
malloc/realloc을 N번 호출한 뒤에 실패시키는 LD_PRELOAD 래퍼를 걸면, hostlist_push 안에서 실패했을 때 의도한 대로 "out of memory"를 출력하고 exit 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.