2016-07-12 6 views
1

Ich arbeite in einer Multi-Prozess-Umgebung mit C++ mit einigen Lua-Bindungen, mit Lua-Funktionen, um einige Aspekte der Prozesse mit einem einzigen freigegebenen Lua-Kontext unter ihnen zu verwalten .Mehrere lua_calls beenden und generieren einen "C-Stack-Überlauf"

Die allgemeine Form, die ich benutze, ist durch das Anhängen bestimmter Ereignisse, Auslösen von Lua-Funktionen, die wiederum erreichen C++ - Code.

schiebe ich zwei Argumente, die auf dem Stack prozessbezogen sind, und dann

lua_call(L, 2, 0); 

Problem Das Problem ist, dass einige spezifische lua_call eine Kill-Funktion (beabsichtigte Verhalten) zu erreichen, aber da das nicht der Fall ist lua_call zurück, der Stapel wird nicht freigegeben. Nach etwa 200 solcher Anrufe gerät Lua wegen eines C-Stack-Überlaufs in Panik.

Ich habe den Lua-Stapel an jedem Haken gedruckt und ich kann sehen, wie er wächst. Ich habe versucht mit lua_pop(L, 2) (Stack wächst um 2 jedes Mal), lua_settop(L, 0) nach Lua verbraucht die Argumente und gibt den Rückruf, kurz vor dem Töten des Prozesses, aber ohne Erfolg.

Ich kann lua_close(L) nicht aufrufen, weil das den Kontext zerstören würde, der unter Prozessen geteilt wird, und würde auf einen Nullkontext durch andere Prozesse ergeben.

+0

Ich denke, die einfachste Lösung ist, Ihren Lua-Kontext nicht zwischen Prozessen zu teilen. (Eigentlich bin ich überrascht, dass das funktioniert) – immibis

+0

Sie müssen eine Art von Sperren verwenden, wenn Sie zwei Threads durch eine Lua-VM gleichzeitig ausführen, dann erhalten Sie undefiniertes Verhalten. –

+0

Warum kehren die Lua-Anrufe nicht zurück? Es stimmt mit der Spezifikation überein, dass Sie Stapeleinträge verlieren werden, wenn Sie dies tun. Wenn Sie "lua_call" mit einigen Argumenten aufrufen, werden die Argumente unterhalb des Funktionsaufrufs durch lua geschützt und der Stack-Frame wird virtuell verschoben, um den Aufruf zu unterstützen. der "ursprüngliche" Stapel wird nur zugänglich, wenn Sie von der Funktion zurückkehren. Sie müssen schließlich von dem Anruf zurückkehren oder diese Einträge sind für immer AFAIK durchgesickert. –

Antwort

0

Meine Problemumgehung ist, anstatt den Prozess, der lua_call ausgibt, sofort zu töten, setze ich eine Markierung und töte sie nur, nachdem der Anruf zurückkommt, sicherstellend keine übrig gebliebenen Stapelrahmen.

Nochmals vielen Dank an Chris Beck für seinen aufschlussreichen Kommentar, wie der Lua-Stack funktioniert.