Entries in .z.s (2)

Why can’t kdb’s debugger tell me exactly which line in the function invoked the error?

q simply does not seem to hold that information during run time. It knows the state of the stack and function undergoing execution prior to the error event, but cannot map the program counter to a specific line in the q code.

Although it can't directly tell you the name of the function in which you've trapped, it does know the body of the current function via the variable .z.s (self). Using .z.s (self), you can use the following handy code to deduce the name of the function:

function_name: {[body]
names: value "\\f";
bodies: value each names;
matches: names where body ~/: bodies;
$[0 = count matches;
' "Not found (try a different namespace?)";
  1 = count matches;
first matches;
/ else
matches]}

Here's how you use it:

q)f: {break}
q)f[]
{break}
'break
q))function_name .z.s
`f
q))

Things get more complicated if you put functions into different namespaces:

q)\d .foo
q.foo)bar: {break}
q.foo)\d .
q).foo.bar[]
{break}
'break
q.foo))`.[`function_name] .z.s
`bar
q.foo))

As you can see, q puts you into the namespace that was in effect at the time the function was defined. You may want to put function_name into a file that you load into every namespace so you don't have to remember to type `.[`function_name].

Note that that namespace that q breaks into is not necessarily the namespace in which the function is defined:

q).foo.baz: {break}
q).foo.baz[]
{break;}
'break
q))function_name .z.s
'Not found (try a different namespace?)
q))\d .foo
q.foo))`.[`function_name] .z.s
`baz
q.foo))

Especially interesting, regarding this last example, is that function_name returns the correct function even though bar and baz have identical bodies:

q.foo))bar
{break}
q.foo)baz
{break}
q.foo))string[bar] ~ string baz
1b
q.foo))bar ~ baz
0b
q.foo))

How do I debug code in kdb?

You can enable error trapping via the -e command line option at kdb start-up:

$ q -e 1

or from the q console

q)\e 1

Upon an error, kdb halts and outputs the body of the function (.z.s (self)) in which the error occurred as well as an error message. You are free to inspect the values of any global or local variables to try to diagnose the source of the problem. At this point you have the following options:

  • type '(single quote) to pop the stack.
  • type :(colon) to resume execution
  • type \(slash) to exit debug mode

There is no ability step into a function call or move up and down the stack.