How to Translate Kernel's Trap Divide Error Rsp:2B6D2Ea40450 to a Source Location

How to translate kernel's trap divide error rsp:2b6d2ea40450 to a source location?

rip is the instruction pointer, rsp is the stack pointer. The stack pointer is not too useful unless you have a core image or a running process.

You can use either addr2line or the disassemble command in gdb to see the line that got the error, based on the ip.


$ cat divtest.c
main()
{
int a, b;

a = 1; b = a/0;
}

$ ./divtest
Floating point exception (core dumped)
$ dmesg|tail -1
[ 6827.463256] traps: divtest[3255] trap divide error ip:400504 sp:7fff54e81330
error:0 in divtest[400000+1000]

$ addr2line -e divtest 400504
./divtest.c:5

$ gdb divtest
(gdb) disass /m 0x400504
Dump of assembler code for function main:
2 {
0x00000000004004f0 : push %rbp
0x00000000004004f1 : mov %rsp,%rbp

3 int a, b;
4
5 a = 1; b = a/0;
0x00000000004004f4 : movl $0x1,-0x4(%rbp)
0x00000000004004fb : mov -0x4(%rbp),%eax
0x00000000004004fe : mov $0x0,%ecx
0x0000000000400503 : cltd
0x0000000000400504 : idiv %ecx
0x0000000000400506 : mov %eax,-0x8(%rbp)

6 }
0x0000000000400509 : pop %rbp
0x000000000040050a : retq

End of assembler dump.

What is the difference between Trap and Interrupt?

A trap is an exception in a user process. It's caused by division by zero or invalid memory access. It's also the usual way to invoke a kernel routine (a system call) because those run with a higher priority than user code. Handling is synchronous (so the user code is suspended and continues afterwards). In a sense they are "active" - most of the time, the code expects the trap to happen and relies on this fact.

An interrupt is something generated by the hardware (devices like the hard disk, graphics card, I/O ports, etc). These are asynchronous (i.e. they don't happen at predictable places in the user code) or "passive" since the interrupt handler has to wait for them to happen eventually.

You can also see a trap as a kind of CPU-internal interrupt since the handler for trap handler looks like an interrupt handler (registers and stack pointers are saved, there is a context switch, execution can resume in some cases where it left off).

Struct RUNTIME_FUNCTION

You can find more information on RUNTIME_FUNCTION and related structures at Microsoft's MSDN.

These structures are generated by the compiler and used to implement structured exception handling. During the execution of your code an exception may occur, and the runtime system needs to be able to walk up the call stack to find a handler for that exception. To do so, the runtime system needs to know the layout of the function prologs, which registers they save, in order to correctly unwind the individual function stack frames. More details are here.

The RUNTIME_FUNCTION is the structure which describes a single function, and it contains the data required to unwind it.

If you generate code at runtime and need to make that code available to the runtime system (because your code calls out to already compiled code which may raise an exception) then you create RUNTIME_FUNCTION instances for each of your generated functions, fill in the UNWIND_INFO for each, and then tell the runtime system by calling RtlAddFunctionTable.



Related Topics



Leave a reply



Submit