Menu

Enhanced Low Level Debugger Interface

Enhanced Low Level debugger Interface

By attaching the user initiated gdb thread to VM, JNI methods dispatching call into VM is invoked just as ordinary C methods. Though synchronization related problems exist, the tool eases debugging. The Enhanced Low Level Debugger Interface dynamically register new method of interest to gdb, and maintain a record so that re-compiled versions are monitored the same way.

1. Display method call stack

Code repo provides a gdb user defined command "afi", which back tracks the call stack, displaying the fp,ret,cmid of each method. This command takes current fp as input.

Example:
Breakpoint 1, staticReturnDouble(primitive, primitive, primitive, primitive, primitive, primitive, primitive, reference, primitive)primitive (B=@0xb,
C=@0x720d9798, S=@0x72057818, I=@0x720dc678, J=@0x381, F=@0x70c30728, D=@0x7173bf88, Ljava/lang/Object;=@0x720eca78, Z=@0x720d9798)
at MethodInvocation.java:118
118 MethodInvocation.java: No such file or directory.
in MethodInvocation.java
(gdb) x/x $rsi+0xa0
0x7000ae78: 0x00000000
(gdb) x/x $rsi+0xc0
0x7000ae98: 0x70a1a8d0
(gdb) disassemble $rip,+32
Dump of assembler code from 0x70c30728 to 0x70c30748:
=> 0x0000000070c30728 <staticReturnDouble(primitive, primitive,="" primitive,="" primitive,="" primitive,="" primitive,="" primitive,="" reference,="" primitive)primitive+0="">: push QWORD PTR [rsi+0xc0]
0x0000000070c3072e <staticReturnDouble(primitive, primitive,="" primitive,="" primitive,="" primitive,="" primitive,="" primitive,="" reference,="" primitive)primitive+6="">: mov QWORD PTR [rsi+0xc0],rsp
....
(gdb) x/x $rsi+0xc0
0x7000ae98: 0x70a1a8d0
(gdb) afi 0x70a1a8d0
0x70a1a8d0: 0x0000000070a1a9b8
cmid/ret/fp
0x70a1a9b0: 0x00000000000022ea
0x70a1a9c0: 0x00000000642f7ccf
0x70a1a9b8: 0x0000000070a1aa28
cmid/ret/fp
0x70a1aa20: 0x00000000000022e9
0x70a1aa30: 0x0000000064373fce
0x70a1aa28: 0x0000000070a1aab0
cmid/ret/fp
0x70a1aaa8: 0x0000000000000f69
0x70a1aab8: 0x00000000643740bd
0x70a1aab0: 0x0000000070a1ab48
cmid/ret/fp
0x70a1ab40: 0x0000000000000f68
0x70a1ab50: 0x00000000643270b6
0x70a1ab48: 0x0000000070a1abf0
...

2. Dynamically register method

With the obtained cmid, users register the unique method with the newly introduced mVw method. The parameters for the mVw method are type,cmid,name. Type are "mth", "obj", "clz" and "typ". Except the first choice, all the others are dispatched to old methods. cmid is the compiled method id. Name is the normalized method name, as obtained from symbolName. Presently, mVw doesn't support method name as explained in unresolved problem section.

Example:
(gdb) call mVw("mth",0x00000000000022ea,"")
(gdb) call mVw("mth",0x00000000000022e9,"")
(gdb) call mVw("mth",0x0000000000000f69,"")
...
(gdb) stepi
0x0000000070c3072e 118 in MethodInvocation.java
(gdb)
0x0000000070c30735 118 in MethodInvocation.java
...
(gdb) bt
#0 0x0000000070c30735 in staticReturnDouble(primitive, primitive, primitive, primitive, primitive, primitive, primitive, reference, primitive)primitive (B=@0xc, C=@0x61, S=@0x38, I=@0x1ed2, J=@0x12345670000, F=@0x4048f5c3, D=@0x400170a3d70a3d71, Ljava/lang/Object;=@0x71659cb8, Z=@0x1)
at MethodInvocation.java:118
#1 0x00000000642d85db in generateReflectiveMethodInvokerInstructions()void ()
#2 0x00000000642f7b48 in outOfLineInvoke(reference, reference, array, primitive)reference (Lorg/jikesrvm/classloader/RVMMethod;=@0x72057818,
Ljava/lang/Object;=@0x0, [Ljava/lang/Object;=@0x720c47f8, Z=@0x1) at Reflection.java:234
#3 0x00000000642f7ccf in invoke(reference, reference, reference, array, primitive)reference (Lorg/jikesrvm/classloader/RVMMethod;=@0x72057818,
Lorg/jikesrvm/runtime/ReflectionBase;=@0x0, Ljava/lang/Object;=@0x0, [Ljava/lang/Object;=@0x720c47f8, Z=@0x1) at Reflection.java:74
#4 0x0000000064373fce in callMethod(reference, reference, array, reference, primitive)reference (Ljava/lang/Object;=@0x0,
Lorg/jikesrvm/classloader/MethodReference;=@0x720629d8, [Ljava/lang/Object;=@0x720c47f8, Lorg/jikesrvm/classloader/TypeReference;=@0x61e649c0,
Z=@0x1) at JNIHelpers.java:428
...

3. Unresolved problems

When a break point is reached, gdb halts execution of all threads. The thread calling the mVw method is initiated by user. It may be on the stack of a native thread or a java thread. AttachCurrentThread is called first, and while all other threads are blocked by gdb, no lock can be owned except those that are free or owned by the current thread. Currently mVw doesn't support registering new method via name.
If a method with a give cmid can't be dynamically registered, the desTyp method is available to find the details of the method, and it is possible to register through the normal approach, that is append it to the methods.to.register variable.

Posted by Da Feng 2012-02-20

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.