Closed
Description
Hi,
When I was an apprentice in the OpenJDK world, I have no idea about How to use gdb to debug C1 compiler's internal error. I always lost in the Assembly
forest :(
Dean, an experienced OpenJDK HotSpot developer, introduced C1Breakpoint
and then
single-stepping si
through the generated code.
So I just implement JitCompBreakpoint
for CoreCLR about Debugging JIT-ed Code With GDB or lldb:
diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp
index 7eb808f..fda3e89 100644
--- a/src/coreclr/src/jit/codegencommon.cpp
+++ b/src/coreclr/src/jit/codegencommon.cpp
@@ -4865,6 +4865,21 @@ void CodeGen::genPushCalleeSavedRegisters()
}
#endif // DEBUG
+#ifdef DEBUG
+ const char* JitCompBreakpoint = getenv("JitCompBreakpoint");
+ if (JitCompBreakpoint)
+ {
+ if (strstr(JitCompBreakpoint, "*") || strstr(compiler->info.compFullName, JitCompBreakpoint))
+ {
+#if defined(_TARGET_ARMARCH_)
+ instGen(INS_brk);
+#elif defined(_TARGET_XARCH_)
+ instGen(INS_int3);
+#endif
+ }
+ }
+#endif
+
#if defined(_TARGET_ARM_)
regMaskTP maskPushRegsFloat = rsPushRegs & RBM_ALLFLOAT;
regMaskTP maskPushRegsInt = rsPushRegs & ~maskPushRegsFloat;
diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp
index 427a1c0..f7add7a 100644
--- a/src/coreclr/src/jit/emitarm64.cpp
+++ b/src/coreclr/src/jit/emitarm64.cpp
@@ -3368,7 +3368,10 @@ void emitter::emitIns(instruction ins)
instrDesc* id = emitNewInstrSmall(EA_8BYTE);
insFormat fmt = emitInsFormat(ins);
- assert(fmt == IF_SN_0A);
+ if (ins != INS_brk)
+ {
+ assert(fmt == IF_SN_0A);
+ }
id->idIns(ins);
id->idInsFmt(fmt);
Then it is able to single-stepping si
through the generated code by setting JitCompBreakpoint enviroment value:
export JitCompBreakpoint="Enumerator[Int64,__Canon][System.Int64,System.__Canon]:Dispose():this"
For X86:
...
{ Start Jitting Method 880 Enumerator[Int64,__Canon][System.Int64,System.__Canon]:Dispose():this (MethodHash=a94d4759) MinOpts
} Jitted Method 880 at 00007fff`7c6a8dd0 method Enumerator[Int64,__Canon][System.Int64,System.__Canon]:Dispose():this size 0000002f
Process 6804 stopped
* thread #7, name = '.NET Finalizer', stop reason = signal SIGTRAP
frame #0: 0x00007fff7c6a8dd2
-> 0x7fff7c6a8dd2: subq $0x10, %rsp
0x7fff7c6a8dd6: leaq 0x10(%rsp), %rbp
0x7fff7c6a8ddb: movq %rdi, -0x8(%rbp)
0x7fff7c6a8ddf: movq %rsi, -0x10(%rbp)
(lldb) si
Process 6804 stopped
* thread #7, name = '.NET Finalizer', stop reason = instruction step into
frame #0: 0x00007fff7c6a8dd6
-> 0x7fff7c6a8dd6: leaq 0x10(%rsp), %rbp
0x7fff7c6a8ddb: movq %rdi, -0x8(%rbp)
0x7fff7c6a8ddf: movq %rsi, -0x10(%rbp)
0x7fff7c6a8de3: movabsq $0x7fff7bfa45e0, %rax ; imm = 0x7FFF7BFA45E0
(lldb) si
Process 6804 stopped
* thread #7, name = '.NET Finalizer', stop reason = instruction step into
frame #0: 0x00007fff7c6a8ddb
-> 0x7fff7c6a8ddb: movq %rdi, -0x8(%rbp)
0x7fff7c6a8ddf: movq %rsi, -0x10(%rbp)
0x7fff7c6a8de3: movabsq $0x7fff7bfa45e0, %rax ; imm = 0x7FFF7BFA45E0
0x7fff7c6a8ded: cmpl $0x0, (%rax)
(lldb) si
Process 6804 stopped
* thread #7, name = '.NET Finalizer', stop reason = instruction step into
frame #0: 0x00007fff7c6a8ddf
-> 0x7fff7c6a8ddf: movq %rsi, -0x10(%rbp)
0x7fff7c6a8de3: movabsq $0x7fff7bfa45e0, %rax ; imm = 0x7FFF7BFA45E0
0x7fff7c6a8ded: cmpl $0x0, (%rax)
0x7fff7c6a8df0: je 0x7fff7c6a8df7
(lldb) si
Process 6804 stopped
* thread #7, name = '.NET Finalizer', stop reason = instruction step into
frame #0: 0x00007fff7c6a8de3
-> 0x7fff7c6a8de3: movabsq $0x7fff7bfa45e0, %rax ; imm = 0x7FFF7BFA45E0
0x7fff7c6a8ded: cmpl $0x0, (%rax)
0x7fff7c6a8df0: je 0x7fff7c6a8df7
0x7fff7c6a8df2: callq 0x7ffff5f276c0 ; JIT_DbgIsJustMyCode at jithelpers.cpp:5149
(lldb)
For ARM64, it is easy to get registers information:
...
{ Start Jitting Enumerator[Int64,__Canon][System.Int64,System.__Canon]:Dispose():this (MethodHash=f16af6a0)
} Jitted Entry 22a at 0000007f`3d731c00 method Enumerator[Int64,__Canon][System.Int64,System.__Canon]:Dispose():this size 0000003c
Thread 7 "corerun" received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread 0x7fb3eb51e0 (LWP 32000)]
0x0000007f3d731c00 in ?? ()
(gdb) x/22i $pc
=> 0x7f3d731c00: brk #0x0
0x7f3d731c04: stp x29, x30, [sp,#-32]!
0x7f3d731c08: mov x29, sp
0x7f3d731c0c: str x0, [x29,#24]
0x7f3d731c10: str x1, [x29,#16]
0x7f3d731c14: mov x0, #0x4658 // #18008
0x7f3d731c18: movk x0, #0x3d19, lsl #16
0x7f3d731c1c: movk x0, #0x7f, lsl #32
0x7f3d731c20: ldr w0, [x0]
0x7f3d731c24: cbz w0, 0x7f3d731c2c
0x7f3d731c28: bl 0x7f3d307bd0
0x7f3d731c2c: nop
0x7f3d731c30: nop
0x7f3d731c34: ldp x29, x30, [sp],#32
0x7f3d731c38: ret
0x7f3d731c3c: ldxrb w15, [x0]
0x7f3d731c40: .inst 0x0040000d ; undefined
0x7f3d731c44: .inst 0xe4e483e1 ; undefined
0x7f3d731c48: .inst 0x00000040 ; undefined
0x7f3d731c4c: .inst 0x00000000 ; undefined
0x7f3d731c50: .inst 0x00000000 ; undefined
0x7f3d731c54: .inst 0x00000000 ; undefined
(gdb) set $pc+=4
(gdb) si
0x0000007f3d731c08 in ?? ()
(gdb) i r x29 x30
x29 0x7fb3eb4000 548479385600
x30 0x7f3d7305ac 546491794860
It is also helpful for MIPS64 RyuJIT porting :)
Request for Comments.
Thanks,
Leslie Zhai