当前位置: 首页 > news >正文

学做文案的网站从化做网站

学做文案的网站,从化做网站,邢台做移动网站,wordpress点击图片暗箱一#xff1a;背景 1. 讲故事 前些天有位朋友找到我#xff0c;说他的软件在客户那边不知道什么原因崩掉了#xff0c;从windows事件日志看崩溃在 clr 里#xff0c;让我能否帮忙定位下#xff0c;dump 也抓到了#xff0c;既然dump有了#xff0c;接下来就上 windbg …一背景 1. 讲故事 前些天有位朋友找到我说他的软件在客户那边不知道什么原因崩掉了从windows事件日志看崩溃在 clr 里让我能否帮忙定位下dump 也抓到了既然dump有了接下来就上 windbg 分析吧。 二WinDbg 分析 1. 为什么崩溃在 clr 一般来说崩溃在clr里都不是什么好事情这预示着 clr 在执行自身代码的时候抛了异常即灾难的 ExecutionEngineException可以用 !t 验证下。 0:000 !t ThreadCount: 18 UnstartedThread: 0 BackgroundThread: 7 PendingThread: 0 DeadThread: 11 Hosted Runtime: noLock ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception0 1 52e8 18998d50 24220 Preemptive 639B0D58:00000000 18c361f0 0 STA System.ExecutionEngineException 1f421120... 既然是灾难性异常那为什么会出现呢可以用 !analyze -v 观察下。 0:000 !analyze -v CONTEXT: 0115a98c -- (.cxr 0x115a98c) eax00000000 ebx00000000 ecx00000000 edx18c364a4 esi00030000 edi18998d50 eip552bfff1 esp0115ae6c ebp0115af24 iopl0 nv up ei pl zr na pe nc cs0023 ss002b ds002b es002b fs0053 gs002b efl00010246 clr!VirtualCallStubManager::ResolveWorker0x33: 552bfff1 8bb968020000 mov edi,dword ptr [ecx268h] ds:002b:00000268???????? Resetting default scopeREAD_ADDRESS: 00000268 STACK_TEXT: 0115af24 552c0698 0115afdc 1f4222c0 00030000 clr!VirtualCallStubManager::ResolveWorker0x33 0115affc 552c070b 0115b010 1f4222c0 00030000 clr!VSD_ResolveWorker0x1d2 0115b024 28a3a949 639b0d38 00000000 00000000 clr!ResolveWorkerAsmStub0x1b 0115b0a4 28a3a8bd 00000000 00000000 00000000 xxxx!xxx ... 我去真无语了我卦中数据看这是一个接口Stub调用的崩溃在这里崩溃真的是少之又少从汇编代码 edi,dword ptr [ecx268h] ds:002b:00000268???????? 上看就是因为 ecx 0 导致的接下来观察下方法的汇编代码。 从汇编上看这个 ecx 其实就是这个方法的 this 指针那为什么 this null 呢这就很奇葩了。 2. 为什么 this null 要想找到这个答案只能看clr源代码简化后如下 PCODE VSD_ResolveWorker(TransitionBlock* pTransitionBlock,TADDR siteAddrForRegisterIndirect,size_t token) {...VirtualCallStubManager::StubKind stubKind VirtualCallStubManager::SK_UNKNOWN;VirtualCallStubManager* pMgr VirtualCallStubManager::FindStubManager(callSiteTarget, stubKind);...target pMgr-ResolveWorker(callSite, protectedObj, representativeToken, stubKind); } 从卦中代码看问题就是 pMgrnull 导致的无语了这个 VirtualCallStubManager::FindStubManager 方法的本意就是根据 callSite的stub的前缀找到对应的 虚调用管理器它的核心逻辑如下 StubKind getStubKind(PCODE stubStartAddress, BOOL usePredictStubKind TRUE) {StubKind predictedKind (usePredictStubKind) ? predictStubKind(stubStartAddress) : SK_UNKNOWN;...if (predictedKind SK_LOOKUP){if (isLookupStub(stubStartAddress))return SK_LOOKUP;}...return SK_UNKNOWN; }VirtualCallStubManager::StubKind VirtualCallStubManager::predictStubKind(TADDR stubStartAddress) {StubKind stubKind SK_UNKNOWN;WORD firstWord *((WORD*)stubStartAddress);if (firstWord 0x05ff){stubKind SK_DISPATCH;}else if (firstWord 0x6850){stubKind SK_LOOKUP;}else if (firstWord 0x8b50){stubKind SK_RESOLVE;}return stubKind; } 接下来需要找到 stubStartAddress 的地址是多少这个只需要提取 ResolveWorker 方法的第一个参数 callSite 即可。 0:000 dp poi(0115afdc) L1 0c740040 0c7460120:000 u 0c746012 0c746012 50 push eax 0c746013 6800000300 push 30000h 0c746018 e9d3a6b748 jmp clr!ResolveWorkerAsmStub (552c06f0) 0c74601d 0000 add byte ptr [eax],al 0c74601f 0000 add byte ptr [eax],al 0c746021 005068 add byte ptr [eax68h],dl 0c746024 0000 add byte ptr [eax],al 0c746026 46 inc esi0:000 dp 0c746012 L1 0c746012 00006850 对比刚才的代码既然都返回来了 SK_LOOKUP 那为什么还是 SK_UNKNOWN 呢 这个也可以通过在线程栈上找到 stubKind 变量得到验证。 0:000 uf 552c0698 ... clr!VSD_ResolveWorker0x1ab: 552c065f 8b85e0ffffff mov eax,dword ptr [ebp-20h] 552c0665 83a5ecffffff00 and dword ptr [ebp-14h],0 552c066c 8d95ecffffff lea edx,[ebp-14h] 552c0672 8b08 mov ecx,dword ptr [eax] 552c0674 e858feffff call clr!VirtualCallStubManager::FindStubManager (552c04d1) 552c0679 ffb5ecffffff push dword ptr [ebp-14h] 552c067f 51 push ecx 552c0680 8bcc mov ecx,esp 552c0682 8931 mov dword ptr [ecx],esi 552c0684 ffb5e8ffffff push dword ptr [ebp-18h] 552c068a 8d8de0ffffff lea ecx,[ebp-20h] 552c0690 51 push ecx 552c0691 8bc8 mov ecx,eax 552c0693 e823f9ffff call clr!VirtualCallStubManager::ResolveWorker (552bffbb) 552c0698 8bf0 mov esi,eax ...0:000 dp 0115affc-0x14 L1 0115afe8 00000000 我感觉这逻辑也只有clr团队帮忙解释我已经搞不清楚了接下来我们回头看托管方法看能不能继续下去。 3. 在托管层寻找突破口 高级调试就是这样一个方向走不通就需要在另一个方向上突破接下来使用 !clrstack 观察一下。 0:000 !clrstack OS Thread Id: 0x52e8 (0) Child SP IP Call Site 0115af50 775c2aac [GCFrame: 0115af50] 0115afac 775c2aac [StubDispatchFrame: 0115afac]xxx.GetListDrawerType(System.String) 0115b02c 28a3a949 xxx.PluginInvoker.InvokeMothod[[System.__Canon, mscorlib]](System.String, System.Object[]) 0115b0b0 28a3a8bd xxx.xxx.OnFinishSizeCheck(Int64) ... 从调用栈来看貌似是用反射来实现功能增强不管怎么说先看下xxxCheck 方法干了什么简化后的代码如下 public string OnFinishSizeCheck(long uuid) {return PluginInvoker.InvokeMothodstring(xxxCheck, new object[1] { uuid }); }public static T InvokeMothodT(string methodName, params object[] args) {IPluginInvoker pluginInvoker GetPluginInvoker();return (T)pluginInvoker.InvokeMothod(methodName, args); } 从代码上可以看到原来是使用 (T)pluginInvoker.InvokeMothod(methodName, args); 实现的接口调用在coreclr层面也能观察得到找到对象 1f4222c0 之后按图索骥即可。 0:000 !do 1f4222c0 Name: xxx.xxx.BusinessAppDomainInvoker MethodTable: 0c73a144 EEClass: 0c6d6f0c Size: 12(0xc) bytes File: E:\xxx\xxx.dll Fields:MT Field Offset Type VT Attr Value Name 0c73a4e8 400000a 4 ....AppDomainManager 0 instance 1f42236c appDomainManager 0c73a2dc 4000009 18 ..., xxx]] 0 static 1f422214 lazy0:000 !dumpmt -md 0c73a144 EEClass: 0c6d6f0c Module: 0c7383dc Name: xxx.xxx.BusinessAppDomainInvoker mdToken: 02000006 File: E:\xxx\xxx.dll BaseSize: 0xc ComponentSize: 0x0 Slots in VTable: 10 Number of IFaces in IFaceMap: 1 -------------------------------------- MethodDesc TableEntry MethodDe JIT Name... 0c6c3400 0c73a110 JIT xxx.xxx.InvokeMothod(System.String, System.Object[])0:000 !do poi(0c73a1440x24) Name: xxx.IPluginInvoker MethodTable: 0c739f30 EEClass: 0c6d6d34 Size: 0(0x0) bytes File: E:\xxx\xxx.dll Fields: None ThinLock owner 1 (18998d50), Recursive 0 对比那个 token30000h 发现什么地方都没有问题奇葩的就是一个简单接口调用就出现了问题仔细观察代码之后发现了两个和别人不一样的地方。 4. 与众不同的地方在哪里 第一个是他的程序是多 AppDomain 的可以用 !dumpdomain 观察。 0:000 !dumpdomain -------------------------------------- System Domain: 55a6caa0 ... -------------------------------------- Shared Domain: 55a6c750 LowFrequencyHeap: 55a6cdc4 Stage: OPEN -------------------------------------- Domain 1: 18b04690 LowFrequencyHeap: 18b04afc Name: DefaultDomain -------------------------------------- Domain 2: 18c361f0 LowFrequencyHeap: 18c3665c ... 第二个是我发现托管调用栈上还有很多 托管C这种混合编程真的是无语了。 到这里我想到了三个办法 1如果可以先把接口方法预热clr会直接把方法入口塞到汇编里就不会再走clr底层逻辑了。 2能否将 托管C 和 C# 隔离不要混合编程。 3重点观察下多Domain下这个托管调用是不是有什么问题。 三总结 这种 多domain 托管C混合C# 编程真出问题了基本上就是无解一般人hold不住无语了。
http://www.hkea.cn/news/14338473/

相关文章:

  • 做网站的计划书互联网信息服务许可证
  • 做外贸怎样免费登录外国网站友情链接收录
  • 教育类网站建设策划书国内seo工具
  • 设备免费做网站推广智联招聘网站怎么做两份简历模板
  • 融资融券配资网站建设网站开发前期功能策划
  • 网站建设如何创业刚做的网站怎么搜索不出来
  • 淄博网站建设推广优化万户网络公司如何
  • 网站平台设计企业公示信息查询系统江西
  • 东莞网站建设公司辉煌大厦南京高固建设公司
  • 低代码建站平台付费小说网站怎么做
  • 简洁大气企业网站源码网络软文广告
  • 长春网站建设首选网诚传媒_国外设计网站排名
  • 怎么做微信领券网站在网站建设中遇到的问题
  • 镇江网站排名优化价格网站开发可选择的方案有
  • 星夜智能建站平台河南建设工程信息网官方网站
  • 德州市建设小学网站网站区域名是什么意思
  • 微软的网站开发软件网站空间管理权限
  • php网站开发工程师招聘网郑州市做网站的公司
  • 怎样搜网站工作组赴哈尔滨
  • 网站名称和备案公司名称不一样全国信用信息公示系统官网
  • 东直门小学的网站建设在线开发app
  • 网站系统管理员湖州医院网站建设方案
  • 新网站建设需要什么网站制作多少钱一个月
  • 可以做英文教师的网站网站项目进度
  • 哈尔滨企业建站网站建设主管的策划案
  • 网站建设 三牛上海自贸区注册企业优惠政策
  • 礼品工艺品网站建设深圳网站建设维护服务
  • 五屏网站建设平台制作相册的软件app免费
  • 站长工具推荐网站UE4做购物网站
  • 旅游网站功能流程图wordpress客户端有什么用