ek9_debug_inspect
Reads what runs recorded - a failure's account, where a value first went wrong, failing and passing runs compared, a report to share - and the current debug session by field (the recorded stop, a frame's locals, path values, the threads), never running the debuggee.
When to use it
After a journalled run or sweep: 'what led to the failure?' is {action:'leadingTo', hypothesis:'...'}; 'when did it first go wrong?' is {action:'firstWhere', condition:'total < 0', hypothesis:'...'}; 'what do the failing runs have that the passing ones do not?' is {action:'compare', hypothesis:'...'}; 'write it up for the team' is {action:'report', hypothesis:'...', finding:'the cause and fix, citing t5 and Orders.ek9:36'} - one page to share. At a stop: 'what is happening where it stopped?' is {action:'stop'}; {action:'evaluate', frameId, paths:['rex.legs', 'names[0]', 'total?']} reads values; {action:'locals', frameId} lists a frame's locals.
When not to use it
- Collecting values at every hit of a line - use
ek9_debug_observe. - Static questions about the code - use
ek9_query_constructorek9_query_flow.
Details
stop answers from the record made AT the stop, so it is exact even after the thread resumes (lastStop). locals and evaluate read the live frame and need the thread still stopped; frame ids are valid until it resumes. A path is name ('.' field | '[' index ']')* ('?')?; one that cannot be followed gives its reason, never a guess. leadingTo reads the run's change journal (the current session's run, or runId from the same project), never the live program, so it answers after the run has ended: the account is every change to the objects the symptom read - their owners' changes and where the value itself came from - with the inputs, the logged calls and earlier symptoms, oldest first; each line opens with its tick. Cite those ticks for every claim. envelope says what the account cannot hold (missed hits, gaps, steps past limit).
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
action | string: stop | locals | evaluate | threads | leadingTo | firstWhere | history | routes | slice | compare | report | what to read; leadingTo, firstWhere, history, routes and slice reduce the run's change journal (history: every change to ONE object, named by its #N), compare (and routes with runs) several runs' journals; report writes those runs as a page to hand a person (index.html, and report.json with the same facts). | |
condition | string | firstWhere: when the value is wrong, as a breakpoint condition: 'total < 0', 'not total?', 'total > 100 and before.total <= 100'; the property's name is its value after a change, before.<name> before it. | |
failing | string: uncaught | anySymptom | exitCode | changeCheck | compare, report: what makes a run a failing one (default uncaught: an Exception or Panic the program did not catch; changeCheck: its journal.changeCheck broke). | |
finding | string | report: your conclusion - the cause and the fix - citing ticks (t5) and lines (Orders.ek9:36); shown as yours in the report's Finding, which the report never writes itself (default: none). | |
frameId | integer | locals / evaluate: a frame id from a stop's frames; locals also takes a value's 'reference' and lists what it holds (a List's items, a Dict's values, an object's fields). | |
from | integer | history, slice: the first tick to include. | |
hypothesis | string | leadingTo, firstWhere, history, routes, slice, compare: REQUIRED - what you expect the answer to confirm or refute, in a sentence; it is kept with the question. | |
limit | integer | leadingTo, history (compare: how many differences; routes: how many routes; slice: how many rows, the first): how many change steps to show, the most recent (default 40); the rest are counted in envelope. | |
object | string | history (required): whose changes to list - an object's identity #N as an earlier answer shows it, e.g. #4 from leadingTo's 't2 change #4.total 0 -> 100' (the owner) or a value's identity; the values one property took are its owner's changes to it. | |
paths | array of string | evaluate: paths such as 'total', 'rex.legs', 'names[0]', 'scores["bob"]', 'total?'. | |
projectDir | string | leadingTo, firstWhere, history, routes, slice, compare: the project whose journals to read (default: the session's) - absolute, or relative to the workspace root. With it they answer after terminate, and in a server that never ran the session. | |
property | string | routes: one of the watched properties, by field ('total') or 'Type.field' (default: every one, each route tagged with its own). | |
runId | string | leadingTo, firstWhere, history, routes, slice: another run's journal in the same project (default: the current session's run, or with projectDir and no session there, the most recent run). | |
runs | array of string | compare, report: the run ids (default: the most recent 20 runs in this project journalling the same property of the same program); routes: the runs to count each route across (default: the one run). | |
symptom | integer | leadingTo: the tick of the symptom to explain (default: the first uncaught exception, else the last symptom); the answer lists the others. | |
to | integer | history: the last tick to include; slice: the tick to stop BEFORE (required). |
See also
- Show me in the IDE: Chapter 23: running the tests, and the Journal
- Show me in the IDE: The Journal: one run
- Show me in the IDE: The Journal: comparing runs
- Part of the investigate_runtime_defect workflow: A runtime failure whose cause is earlier: journal the value over failing AND passing runs -> compare -> leadingTo -> firstWhere -> confirm with one input changed -> report with a finding.