{"record":{"id":"f387cc55392c3560","repo":"numpy/numpy","slug":"stop-s-statement-executed","errorCode":null,"errorMessage":"STOP %s statement executed\n","messagePattern":"STOP (.+?) statement executed\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"numpy/linalg/lapack_lite/f2c.c","lineNumber":750,"sourceCode":"#undef abs\n#undef min\n#undef max\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nvoid f_exit(void);\n\nint s_stop(char *s, ftnlen n)\n#endif\n{\nint i;\n\nif(n > 0)\n\t{\n\tfprintf(stderr, \"STOP \");\n\tfor(i = 0; i<n ; ++i)\n\t\tputc(*s++, stderr);\n\tfprintf(stderr, \" statement executed\\n\");\n\t}\n#ifdef NO_ONEXIT\nf_exit();\n#endif\nexit(0);\n\n/* We cannot avoid (useless) compiler diagnostics here:\t\t*/\n/* some compilers complain if there is no return statement,\t*/\n/* and others complain that this one cannot be reached.\t\t*/\n\nreturn 0; /* NOT REACHED */\n}\n#ifdef __cplusplus\n}\n#endif","sourceCodeStart":732,"sourceCodeEnd":768,"githubUrl":"https://github.com/numpy/numpy/blob/e117b3ca4edacf581f440dccfd7f3242f0312afa/numpy/linalg/lapack_lite/f2c.c#L732-L768","documentation":"s_stop in numpy/linalg/lapack_lite/f2c.c:743 is the f2c runtime stub backing Fortran's `STOP [msg]` statement for the C-translated LAPACK used by numpy.linalg. It prints `STOP <msg> statement executed` to stderr and then calls exit(0) (line 758), terminating the entire Python process. There is no exception to catch — the interpreter is simply replaced — and because the exit code is 0 the failure looks like a clean exit, masking the crash. In shipped lapack_lite this path is not normally reachable because LAPACK reports errors through XERBLA rather than STOP, so encountering it usually indicates an internal LAPACK branch, a custom/patched lapack_lite, or other f2c-compiled Fortran linked into the interpreter executing a STOP.","triggerScenarios":"A Fortran routine translated via f2c executes a STOP statement. Concretely: a numpy.linalg call routes into lapack_lite and hits an abnormal/internal branch that STOPs; or user-supplied f2c-compiled Fortran linked into the process runs a STOP; or a custom/modified lapack_lite build introduces a STOP reachable on certain inputs.","commonSituations":"Passing pathological matrix inputs (degenerate shapes, extreme scaling, NaN/Inf) that drive a LAPACK routine into an unexpected branch; using a custom or patched lapack_lite build; linking application f2c-compiled Fortran that uses STOP for error handling; subtle differences across numpy/lapack_lite versions or build configurations.","solutions":["Validate and sanitize inputs (shape, squareness, dtype, finiteness, contiguity) before the numpy.linalg call so the LAPACK routine never reaches an abnormal branch.","Reproduce the call in a throwaway child process to confirm which invocation triggers the STOP — the parent dies with exit code 0, so the only way to keep working is process isolation.","If a plain numpy.linalg call on well-formed input reproduces it, file a NumPy bug with a minimal reproducer; reaching STOP from numpy.linalg indicates a lapack_lite issue.","Avoid linking custom f2c-compiled Fortran that uses STOP into the interpreter — replace STOP with XERBLA / error-return paths."],"exampleFix":"# before — unvalidated input can drive LAPACK into a STOP branch,\n# killing the whole process with exit(0) and no traceback\nv = np.linalg.eigvals(M)\n\n# after — sanitize inputs and isolate the call in a subprocess so a\n# STOP/exit(0) cannot take down the main process\nimport numpy as np, subprocess, sys, json\nM = np.ascontiguousarray(M, dtype=np.float64)\nassert M.ndim == 2 and M.shape[0] == M.shape[1], \"M must be 2-D square\"\nassert np.isfinite(M).all(), \"M must not contain NaN/Inf\"\nprog = (\"import numpy as np, json, sys;\"\n        \"r=np.linalg.eigvals(np.array(json.loads(sys.stdin.read())));\"\n        \"sys.stdout.write(json.dumps(r.tolist()))\")\np = subprocess.run([sys.executable, \"-c\", prog],\n                   input=json.dumps(M.tolist()), capture_output=True, text=True)\nif p.returncode != 0 or \"STOP\" in p.stderr:\n    raise RuntimeError(\"LAPACK STOP killed subprocess: \" + p.stderr)\nv = np.array(json.loads(p.stdout))","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef validate_linalg_matrix(M, square=True):\n    \"\"\"Sanitize a matrix for numpy.linalg so LAPACK never hits an abnormal\n    (STOP) branch. Returns a contiguous float array.\"\"\"\n    M = np.ascontiguousarray(M)\n    if square:\n        if M.ndim != 2 or M.shape[0] != M.shape[1]:\n            raise ValueError(f\"expected 2-D square matrix, got shape {M.shape}\")\n    if M.dtype.kind != \"f\":\n        M = M.astype(np.float64)\n    if not np.isfinite(M).all():\n        raise ValueError(\"input contains NaN or Inf\")\n    return M","typeGuard":"import numpy as np\n\ndef is_valid_matrix(M, square=True):\n    ok = isinstance(M, np.ndarray) and M.ndim == 2 and M.dtype.kind == \"f\" and np.isfinite(M).all()\n    if square:\n        ok = ok and M.shape[0] == M.shape[1]\n    return ok","tryCatchPattern":"# exit(0) inside the C extension CANNOT be caught by try/except —\n# the whole interpreter dies. The only robust pattern is subprocess\n# isolation, treating any 'STOP ... statement executed' or exit 0 as failure.\nimport subprocess, sys, json\n\ndef safe_linalg(fn_code, M):\n    \"\"\"fn_code is a snippet that reads JSON M on stdin and writes JSON result.\"\"\"\n    p = subprocess.run([sys.executable, \"-c\", fn_code],\n                       input=json.dumps(np.asarray(M).tolist()),\n                       capture_output=True, text=True)\n    if p.returncode != 0 or \"STOP\" in p.stderr:\n        raise RuntimeError(\"LAPACK STOP killed subprocess (rc=%d): %s\"\n                           % (p.returncode, p.stderr))\n    return json.loads(p.stdout)","preventionTips":["Always validate shape, squareness, dtype, and finiteness before numpy.linalg calls.","Treat any 'STOP ... statement executed' plus exit code 0 as a LAPACK internal failure, never a clean exit.","Run exploratory LAPACK calls in a subprocess so a STOP/exit(0) cannot take down the main process.","Report reproducible cases on well-formed inputs to NumPy — STOP should not be reachable from numpy.linalg; it usually signals a lapack_lite bug or custom f2c Fortran misuse."],"tags":["lapack","fortran","f2c","numpy-linalg","process-exit"],"analyzedSha":"e117b3ca4edacf581f440dccfd7f3242f0312afa","analyzedAt":"2026-08-07T01:25:31.049Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}