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))