Lock leak: controlled reproduction attempts and method (not reproduced), enqueue reader; restart plan for 12 October
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
71
scripts_probe/killtest.py
Normal file
71
scripts_probe/killtest.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""Controlled kill: a client sends sap_push_source (testclasses include) and is killed with SIGKILL `delay` seconds
|
||||
after the request left. Then the enqueue table is read and a second write is tried."""
|
||||
import json, os, signal, subprocess, sys, time
|
||||
sys.path.insert(0, "/Users/erhankeseli/projects/abap-llm/harness/scripts_probe")
|
||||
from lockprobe import *
|
||||
|
||||
MAIN = """CLASS {n} DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
||||
PUBLIC SECTION.
|
||||
METHODS run RETURNING VALUE(rv) TYPE i.
|
||||
ENDCLASS.
|
||||
CLASS {n} IMPLEMENTATION.
|
||||
METHOD run.
|
||||
rv = 1.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
"""
|
||||
def tc(extra):
|
||||
body = "".join(" cl_abap_unit_assert=>assert_equals( act = %d exp = %d ).\n" % (i, i) for i in range(extra))
|
||||
return ("CLASS ltc DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.\n PRIVATE SECTION.\n METHODS t1 FOR TESTING.\n"
|
||||
"ENDCLASS.\nCLASS ltc IMPLEMENTATION.\n METHOD t1.\n" + body + " ENDMETHOD.\nENDCLASS.\n")
|
||||
|
||||
VICTIM = r'''
|
||||
import sys, json
|
||||
sys.path.insert(0, "/Users/erhankeseli/projects/abap-llm/harness")
|
||||
from harness.adt_client import load_env; load_env("/Users/erhankeseli/projects/abap-llm/harness/.env")
|
||||
from harness.mcp_client import McpClient
|
||||
args = json.loads(sys.argv[1])
|
||||
m = McpClient().open()
|
||||
print("SENT", flush=True)
|
||||
m.call("sap_push_source", args)
|
||||
print("DONE", flush=True)
|
||||
'''
|
||||
|
||||
def attempt(delay, n, extra=40):
|
||||
name = "ZPROBE0KL_%03d" % n
|
||||
with McpClient() as m:
|
||||
print("create", m.call("sap_create_object", {"objectType": "CLAS", "objectName": name, "packageName": "$TMP", "description": "kill test"})[1][:60])
|
||||
print("main ", m.call("sap_push_source", {"objectType": "CLAS", "objectName": name, "source": MAIN.format(n=name.lower())})[1][:70])
|
||||
args = {"objectType": "CLAS", "objectName": name, "includeType": "testclasses", "source": tc(extra)}
|
||||
p = subprocess.Popen([sys.executable, "-c", VICTIM, json.dumps(args)], stdout=subprocess.PIPE, text=True)
|
||||
assert p.stdout.readline().strip() == "SENT"
|
||||
t0 = time.time()
|
||||
time.sleep(delay)
|
||||
done_before_kill = p.poll() is not None
|
||||
try:
|
||||
os.kill(p.pid, signal.SIGKILL)
|
||||
except ProcessLookupError:
|
||||
done_before_kill = True
|
||||
p.wait()
|
||||
print("victim killed %.2f s after the request was sent (finished before kill: %s)" % (time.time() - t0, done_before_kill))
|
||||
time.sleep(3)
|
||||
out = {"name": name, "delay": delay}
|
||||
with McpClient() as m:
|
||||
out["enqueue"] = read_locks(m)
|
||||
e, t = m.call("sap_push_source", {"objectType": "CLAS", "objectName": name, "includeType": "testclasses", "source": tc(extra + 1)})
|
||||
out["second_write"] = t[:300]
|
||||
e, t = m.call("sap_push_element", {"objectType": "CLAS", "objectName": name, "element": "RUN", "source": " METHOD run.\n rv = 2.\n ENDMETHOD.\n"})
|
||||
out["push_element"] = t[:300]
|
||||
out["leak"] = "currently editing" in out["second_write"] or "[LOCK]" in out["second_write"] or "[LOCK]" in out["push_element"]
|
||||
if not out["leak"]:
|
||||
out["delete"] = delete_uris(["/sap/bc/adt/oo/classes/" + name.lower()])
|
||||
return out
|
||||
|
||||
if __name__ == "__main__":
|
||||
delays = [float(x) for x in sys.argv[1].split(",")]
|
||||
n0 = int(sys.argv[2]) if len(sys.argv) > 2 else 1
|
||||
for i, d in enumerate(delays):
|
||||
o = attempt(d, n0 + i, int(sys.argv[3]) if len(sys.argv) > 3 else 40)
|
||||
print(json.dumps({k: (v if k != "enqueue" else v[:700]) for k, v in o.items()}, indent=1))
|
||||
if o["leak"]:
|
||||
print("LEAK at delay", d, "- stopping, object", o["name"], "needs SM12"); break
|
||||
Reference in New Issue
Block a user