Monday, 4 April 2011

Tales of an Interrupt -- ud2a

Debugging interrupt routines is tiring - anything wrong and BOOM!

So, whilst enabling lots of fbt probes, I was finding AS4 kernels
dying on me. Didnt appear to happen on other kernels, but probably
could/would do.

On investigation, we had executed an invalid instruction. Weird, as
in theory, the dtrace disassembler should just *work*.

But it turns out that because Linux uses judicious use of inlined assembler
code, we had hit a problem. The BUG_ON macro in the kernel, used for
asserting broken behavior (typically of a driver), is implemented by
utilising an invalid instruction. The invalid instruction (UD2A) is great -
we handle that ok, but subsequent to this instruction is a 10 byte field
which encodes the file/linenumber of where the bug happened.


Rather than have the compiler embed lots of __FILE__ strings into the kernel
memory, the strings are uniquified and stored in a separate lookup table,
utilising tricks of the GCC compiler.

Of course, Solaris doesnt do this - and so the FBT code need not worry about
this. (But FreeBSD and MacOSX *could do* if they so choose).

A quick path to the prov_common.c file stops us tripping over and losing
sync with the instruction stream, and this fixes the problem with:

$ dtrace -n fbt::a*:

Post created by CRiSP v10.0.3b-b5955

No comments:

Post a Comment