在龙芯上调试CoreCLR
dotnet for mips64 的 ea 版本已经发布
https://github.com/gsvm/loongson-dotnet/releases
在龙芯上调试CoreCLR
由于lldb在龙芯上工作不正常[1],只有gdb可以用来调试CoreCLR。
因为需要调试JIT代码,所以我们关上gdb分页,不处理SIG34信号:
$ cat ~/.gdbinit
set pagination off
handle SIG34 nostop noprint
调试JIT代码
export CORE_LIBRARIES=/home/loongson/corefx-3.1-Linux.mips64.Debug
export COMPlus_JitFunctionTrace=1
export COMPlus_JitHalt="Main"
gdb -ex=r --args ./bin/Product/Linux.mips64.Debug/corerun /home/loongson/Hello.dll | tee gdb.log
JitHalt="Main"可以在Main方法的序言处插入break指令,然后我们跳过break指令:
(gdb) set $pc+=4
(gdb) x/22i $pc-440xff7c983aac: li zero,0x730xff7c983ab0: nop0xff7c983ab4: 0xf200000xff7c983ab8: sdc1 $f2,-6100(s6)0xff7c983abc: dsra32 zero,zero,0x30xff7c983ac0: 0x7cc11db80xff7c983ac4: dsra32 zero,zero,0x30xff7c983ac8: 0x7cc494580xff7c983acc: dsra32 zero,zero,0x30xff7c983ad0: nop0xff7c983ad4: break
=> 0xff7c983ad8: daddiu sp,sp,-320xff7c983adc: sd s8,0(sp)0xff7c983ae0: sd ra,8(sp)0xff7c983ae4: move s8,sp0xff7c983ae8: sd a0,24(s8)0xff7c983aec: lui a0,0xff0xff7c983af0: ori a0,a0,0x7caf0xff7c983af4: dsll a0,a0,0x100xff7c983af8: ori a0,a0,0x7a880xff7c983afc: lw a0,0(a0)0xff7c983b00: sltiu at,a0,1
查看一下传参整型寄存器的值:
(gdb) i r a0
a0: 0xff5800fa28
(gdb) x/g 0xff5800fa28
0xff5800fa28: 0x000000ff7caf7c30
然后用si指令级的单步跟踪。
还可以使用“硬”watchpoint[2]调试GC相关问题:
(gdb) watch *0xff68001bf8
Hardware watchpoint 1: *0xff68001bf8
(gdb) c
Continuing....
Thread 1 "corerun" hit Hardware watchpoint 1: *0xff68001bf8Old value = 0
New value = 1476465840
JIT_WriteBarrier () at /home/loongson/coreclr/src/vm/mips64/asmhelpers.S:206(gdb) c
Continuing....
Thread 1 "corerun" hit Hardware watchpoint 1: *0xff68001bf8Old value = 1476465840
New value = 1476577368
JIT_WriteBarrier () at /home/loongson/coreclr/src/vm/mips64/asmhelpers.S:206
如何跟踪是“谁”生成的JIT代码?
测试用例:JIT/Methodical/Invoke/thiscall/dbgthisnull/dbgthisnull.exe[3]
加压JIT、GC的时候,该测试用例复现段错误:
export CORE_LIBRARIES=/home/loongson/corefx-3.1-Linux.mips64.Debug
export COMPlus_JitFunctionTrace=1
export COMPlus_JitStress=2
export COMPlus_GCStress=1
export COMPlus_HeapVerify=1
gdb -ex=r --args ./bin/Product/Linux.mips64.Debug/corerun ./bin/tests/Linux.mips64.Debug/JIT/Methodical/Invoke/thiscall/_dbgthisnull/_dbgthisnull.exe | tee gdb.log
我们发现该测试用例“故意”造空指针访存:
Program received signal SIGSEGV, Segmentation fault.
0x000000ff7c985948 in ?? ()
(gdb) x/22i $pc-440xff7c98591c: dext a0,a0,0x0,0x80xff7c985920: sltiu at,a0,10xff7c985924: beqz at,0xff7c9859440xff7c985928: nop0xff7c98592c: b 0xff7c98596c0xff7c985930: nop0xff7c985934: nop0xff7c985938: nop0xff7c98593c: nop0xff7c985940: nop0xff7c985944: ld a0,32(s8)
=> 0xff7c985948: ldc1 $f0,8(a0)0xff7c98594c: sdc1 $f0,24(s8)0xff7c985950: nop0xff7c985954: b 0xff7c9859a00xff7c985958: nop0xff7c98595c: nop0xff7c985960: nop0xff7c985964: nop0xff7c985968: nop0xff7c98596c: bal 0xff7c9859740xff7c985970: nop
(gdb) i r a0
a0: 0x0
那么ldc1 $f0,8(a0)这条指令是由“谁”生成的呢?
0x000000ff7c985948 in ?? ()
(gdb) x/76i 0x000000ff7c915948-1520xff7c9158b0: daddiu sp,sp,-48 <-------- CodeGen::genFnProlog -> CodeGen::genAllocLclFrame0xff7c9158b4: sd s8,0(sp) -> CodeGen::genPushCalleeSavedRegisters0xff7c9158b8: sd ra,8(sp) -> ...0xff7c9158bc: move s8,sp0xff7c9158c0: sd a0,32(s8)0xff7c9158c4: sw a1,40(s8) <-------- CodeGen::genFnProlog0xff7c9158c8: lui a0,0xff <----- set_Reg_To_Imm0xff7c9158cc: ori a0,a0,0x7ca80xff7c9158d0: dsll a0,a0,0x100xff7c9158d4: ori a0,a0,0x7b50 <----- set_Reg_To_Imm end0xff7c9158d8: lw a0,0(a0)0xff7c9158dc: sltiu at,a0,1 <---------- CodeGen::genCodeForCompare0xff7c9158e0: beqz at,0xff7c9159000xff7c9158e4: nop0xff7c9158e8: b 0xff7c9159180xff7c9158ec: nop0xff7c9158f0: nop0xff7c9158f4: nop0xff7c9158f8: nop0xff7c9158fc: nop <----------- CodeGen::genCodeForCompare0xff7c915900: lui a0,0xff0xff7c915904: ori a0,a0,0xf6a00xff7c915908: dsll a0,a0,0x100xff7c91590c: ori a0,a0,0x8fa80xff7c915910: jalr a00xff7c915914: move t9,a00xff7c915918: lw a0,40(s8)0xff7c91591c: dext a0,a0,0x0,0x80xff7c915920: sltiu at,a0,1 <---------- CodeGen::genCodeForCompare0xff7c915924: beqz at,0xff7c9159440xff7c915928: nop0xff7c91592c: b 0xff7c91596c0xff7c915930: nop0xff7c915934: nop0xff7c915938: nop0xff7c91593c: nop0xff7c915940: nop <----------- CodeGen::genCodeForCompare0xff7c915944: ld a0,32(s8)
=> 0xff7c915948: ldc1 $f0,8(a0)0xff7c91594c: sdc1 $f0,24(s8)0xff7c915950: nop0xff7c915954: b 0xff7c9159a00xff7c915958: nop0xff7c91595c: nop0xff7c915960: nop0xff7c915964: nop0xff7c915968: nop0xff7c91596c: bal 0xff7c9159740xff7c915970: nop0xff7c915974: li at,0x440xff7c915978: daddu a0,at,ra0xff7c91597c: ldc1 $f0,0(a0)0xff7c915980: sdc1 $f0,24(s8)0xff7c915984: nop0xff7c915988: b 0xff7c9159a00xff7c91598c: nop0xff7c915990: nop0xff7c915994: nop0xff7c915998: nop0xff7c91599c: nop0xff7c9159a0: ldc1 $f0,24(s8)0xff7c9159a4: ld ra,8(sp) <---------- CodeGen::genFnEpilog -> CodeGen::genPopCalleeSavedRegisters0xff7c9159a8: ld s8,0(sp) -> ...0xff7c9159ac: daddiu sp,sp,480xff7c9159b0: jr ra0xff7c9159b4: nop <---------- CodeGen::genFnEpilog...
ldc1 $f0,8(a0)是由emitter::emitInsLoadStoreOp和emitter::emitIns_R_R_I生成。你可以“故意”修改src/jit/codegenmips64.cpp[4]的CodeGen::genCodeForIndir,添加冗余的nop指令:
diff --git a/src/jit/codegenmips64.cpp b/src/jit/codegenmips64.cpp
index ef18106..465bc17 100644
--- a/src/jit/codegenmips64.cpp
+++ b/src/jit/codegenmips64.cpp
@@ -8290,6 +8290,7 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree)}getEmitter()->emitInsLoadStoreOp(ins, emitActualTypeSize(type), targetReg, tree);
+ instGen(INS_nop);if (emitBarrier){
重新编译,就可以看到“故意”生成的冗余nop指令:
(gdb) x/22i $pc-440xff7c936560: dext a0,a0,0x0,0x80xff7c936564: sltiu at,a0,10xff7c936568: beqz at,0xff7c9365880xff7c93656c: nop0xff7c936570: b 0xff7c9365b40xff7c936574: nop0xff7c936578: nop0xff7c93657c: nop0xff7c936580: nop0xff7c936584: nop0xff7c936588: ld a0,32(s8)
=> 0xff7c93658c: ldc1 $f0,8(a0)
=> 0xff7c936590: nop0xff7c936594: sdc1 $f0,24(s8)0xff7c936598: nop0xff7c93659c: b 0xff7c9365e80xff7c9365a0: nop0xff7c9365a4: nop0xff7c9365a8: nop0xff7c9365ac: nop0xff7c9365b0: nop0xff7c9365b4: bal 0xff7c9365bc0xff7c9365b8: nop
还可以通过grep ldc1 -rn src/jit/来了解访存相关的代码生成。因为ldc1 $f0,8(a0)属于RRI指令形式,所以可以在emitter::emitIns_R_R_I“故意”加入断言:
diff --git a/src/jit/emitmips64.cpp b/src/jit/emitmips64.cpp
index 06b574d..9d19a52 100644
--- a/src/jit/emitmips64.cpp
+++ b/src/jit/emitmips64.cpp
@@ -2513,6 +2513,7 @@ void emitter::emitIns_R_R_I(assert((-32768 <= imm) && (imm <= 32767));assert(isFloatReg(reg1));assert(isGeneralRegisterOrR0(reg2));
+ assert(imm != 8 && reg1 != REG_F0 && reg2 != REG_A0);break;case INS_c_f_s:
gdb bt一下就能知道具体的函数(例如:emitter::emitInsLoadStoreOp)以及行数。
1. https://github.com/dotnet/runtime/issues/37405
2. https://hev.cc/2758.html
3. https://github.com/gsvm/coreclr/blob/mips64-port/tests/src/JIT/Methodical/Invoke/thiscall/_dbgthisnull.ilproj
4. https://github.com/gsvm/coreclr/blob/mips64-port/src/jit/codegenmips64.cpp
相关文章:
龙芯团队完成CoreCLR MIPS64移植,在github开源
Asp.Net终于可以在龙芯服务器上运行啦:Jexus成功完成对国产系列CPU的适配
.NET Core 对龙芯的支持情况和对 .NET Core 开发嵌入式的思考
龙芯团队 在移值 MIPS64 下的.NET Core 进度速报
在龙芯上调试CoreCLR相关推荐
- 龙芯团队完成CoreCLR MIPS64移植,在github开源
国产龙芯的软件生态之中.NET不会缺席,毕竟 C# 与 .NetCore/Mono 也是全球几大主流的编程语言和运行平台之一,最近一段时间听到太多的鼓吹政务领域不支持.NET, 大家都明白这是某些人为 ...
- 在龙芯上探索数据库虚拟化
http://www.loongson.cn/news/company/675.html 数据库虚拟化 云计算是未来,而虚拟化技术则是云计算的基石.在过去10年中,我们见证了虚拟化技术的蓬勃发展.目前 ...
- 我的世界java百度什么电脑玩好_【我的世界】为了在龙芯电脑上玩Minecraft(我的世界)我做了什么_玩得好游戏攻略...
为了在龙芯上玩Minecraft,拼了!先上跑起来的视频. 作为多年的Minecraft玩家,这个残余游戏消磨了我多量的时间.于是想着Minecraft Java版要是能在龙芯上跑起来就好了. 冷假前 ...
- 龙芯平台python答案_在龙芯平台上自己编写原创应用——“动态壁纸”
原标题:在龙芯平台上自己编写原创应用--"动态壁纸" 一.为何要在龙芯平台上编写"动态壁纸"? 龙芯3A3000桌面电脑的用户越来越多了,人们都想在龙芯电脑上有 ...
- 如何在龙芯3B4000上部署基于.Net Core 开发的物联网平台IoTSharp
今天很开心的拿到了龙芯的测试服务器账号, 先上图show一下, 双核, 8G内存, 50G硬盘. 架构 mips64el 登录后, 显示为 uos 及其网址信息: 接下来, 二话不说, 我们开始下载龙 ...
- 龙芯发布.NET 6.0.100开发者内测版
龙芯在龙芯开源社区发布了LoongArch64-.NET-SDK-6.0.100开发者内测版的新闻 ,龙芯.NET基于上游社区 版本 适配支持龙芯平台架构.目前支持LoongArch64架构和MIPS ...
- 龙芯.NET正式发布 开源共享与开发者共成长
2020年12月19日,2020中国. NET开发者大会于苏州盛大开幕.本次大会以"开源.共享.创新"为主题,以线下城市苏州为中心,覆盖北京.上海.深圳.广州.长沙.成都.厦门.胶 ...
- 龙芯开源社区上线.NET主页
龙芯团队从2019年7 月份开始着手.NET Core的MIPS64支持研发,经过将近一年的研发,在2020年6月18日完成了里程碑性的工作,在github CoreCLR 仓库:https://gi ...
- 龙芯服务器部署WEB服务的体验和详细步骤
http://www.loongson.cn/news/company/511.html 2016年8月,通过龙芯俱乐部的<龙芯团购>(网址http://www.loongsonclub. ...
最新文章
- POJ 3278 Catch That Cow
- 数据表格搜索php代码_手把手教学:提取PDF各种表格文本数据(附代码)
- QT的QScriptValue类的使用
- 数平精准推荐 | OCR技术之数据篇
- MySQL多实例配置
- linux打开mysql某张表_Linux——MySQL多表连接
- 免费录屏、最快截图、装X必备、看完工作学习效率直接翻倍
- kubernetes 简介:调度器和调度算法((Affinity/Anti-Affinity, Taints and Tolerations, 自定义调度器 )
- Atitit.远程接口 监控与木马 常用的api 标准化v2 q216
- 泛微E8调整附件大小和属性
- 深入理解TTL 与 CMOS 电路
- 关于QQ游戏大厅的架构我也想说几句
- 服务器带宽打开网页很慢,移动宽带打开网页慢?两招治本移动宽带打开网页速度慢的解决方法...
- 电赛 电容触摸串口屏
- 通过SnmpWalk获取服务器状态信息
- 怎么重装服务器的系统,怎么重装服务器操作系统
- 50个最好的firefox扩展让你尽情冲浪
- 【企业动态】开启新征程,谱写新篇章 | 数商云喜迎乔迁
- 用技巧] Http请求偶尔超时+总结各种超时死掉的可能和相应的解决办法
- 伺服电机各种运行模式
热门文章
- 数据可视化(9)--数据可视化6步法
- 12种方法返回2个文件路径之间的公共基路径ExtractBasePath
- Unity中Time.deltaTime的含义及其应用
- 充分利用Microsoft Planner的6种方法
- google +按钮_如何禁用或改善Google的Google+集成
- NetCore2.0Web应用之Startup
- 使用SMART监控Ubuntu
- 查看Linux进程CPU过高具体的线程堆栈(不中断程序)
- MySQL存储过程相互调用
- matlab提速技巧(自matlab帮助文件)