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

湘潭网站建设 搜索磐石网络站长之家权重

湘潭网站建设 搜索磐石网络,站长之家权重,做dm页网站,jquery扁平自适应网站html5模板一#xff1a;背景 1. 讲故事 前些天微信上有位朋友找到我#xff0c;说他的程序偶发崩溃#xff0c;分析了个把星期也没找到问题#xff0c;耗费了不少人力物力#xff0c;让我能不能帮他看一下#xff0c;给我申请了经费#xff0c;哈哈#xff0c;遇到这样的朋友就…一背景 1. 讲故事 前些天微信上有位朋友找到我说他的程序偶发崩溃分析了个把星期也没找到问题耗费了不少人力物力让我能不能帮他看一下给我申请了经费哈哈遇到这样的朋友就是爽快刚好周二晚上给调试训练营的朋友分享 GC标记阶段 相关知识而这个dump所展示的问题是对这块知识的一个很好的巩固接下来我们开始分析吧。 二WinDbg分析 1. 为什么会崩溃 要想找到崩溃原因还是用老命令 !analyze -v 输出如下 0:005 !analyze -v CONTEXT: (.ecxr) eax063ce258 ebx07b90000 ecx0063552e edx0063552e esi03070909 edi03070909 eip71954432 esp063ce220 ebp063ce23c iopl0 nv up ei pl nz na pe nc cs0023 ss002b ds002b es002b fs0053 gs002b efl00010206 clr!WKS::gc_heap::mark_object_simple0x12: 71954432 8b0f mov ecx,dword ptr [edi] ds:002b:03070909???????? Resetting default scopeEXCEPTION_RECORD: (.exr -1) ExceptionAddress: 71954432 (clr!WKS::gc_heap::mark_object_simple0x00000012)ExceptionCode: c0000005 (Access violation)ExceptionFlags: 00000001 NumberParameters: 2Parameter[0]: 00000000Parameter[1]: 03070909 Attempt to read from address 03070909STACK_TEXT: 063ce23c 719543fc 063ce258 0a76cc88 71954260 clr!WKS::gc_heap::mark_object_simple0x12 063ce25c 71950b62 0a76cc88 063cec88 00000000 clr!WKS::GCHeap::Promote0xa8 ... 063cec28 71950fa3 71950da0 063cec40 00000500 clr!Thread::StackWalkFrames0x9d 063cec4c 7195103e 063cec88 00000002 00000000 clr!standalone::ScanStackRoots0x43 063cec68 71954038 0079cb88 063cec88 00080101 clr!GCToEEInterface::GcScanRoots0xdb 063cecc0 71953225 00080101 00000000 00000001 clr!WKS::gc_heap::mark_phase0x17e 063cece0 7195355b 71f75da0 00000000 00000001 clr!WKS::gc_heap::gc10xae 063cecf8 71953665 71f75fb4 71f75fb4 00000000 clr!WKS::gc_heap::garbage_collect0x367 063ced18 7195376a 00000000 00000000 71f75fb4 clr!WKS::GCHeap::GarbageCollectGeneration0x1bd ... 从卦中信息看当前执行流处于GC标记阶段并且是在各个线程栈上寻找用户根在寻找的过程中踩到了坏内存接下来需要捋一下是什么逻辑踩到的可以用 u 反汇编一下。 0:005 u WKS::gc_heap::mark_object_simple clr!WKS::gc_heap::mark_object_simple: 71954420 55 push ebp 71954421 8bec mov ebp,esp 71954423 83ec18 sub esp,18h 71954426 8b4508 mov eax,dword ptr [ebp8] 71954429 57 push edi 7195442a 8b38 mov edi,dword ptr [eax] 7195442c 89bde8ffffff mov dword ptr [ebp-18h],edi 71954432 8b0f mov ecx,dword ptr [edi] ... 从汇编逻辑看这是将方法的第一个参数进行解引用参考 coreclr 的源码。 void gc_heap::mark_object_simple(uint8_t** po THREAD_NUMBER_DCL) {uint8_t* o *po;if (gc_mark1(o)){...} } 结合C代码edi03070909 就是上面的o也就是需要标记的托管对象但现在这个 o 是一个坏对象那为什么会坏掉呢 2. 为什么 o 坏掉了 按照过往经验肯定是托管堆损坏了可以用 !verifyheap 观察下。 0:005 !verifyheap No heap corruption detected. 从卦中看我去托管堆居然是好的过往经验在这个dump里被击的粉碎接下来要往哪里突破呢 可以观察下这个托管地址和当前的托管segment在空间距离上的特征命令输出如下 0:005 !address 03070909Usage: unknown Base Address: 02ca2000 End Address: 036f0000 Region Size: 00a4e000 ( 10.305 MB) State: 00002000 MEM_RESERVE Protect: info not present at the target Type: 00020000 MEM_PRIVATE Allocation Base: 026f0000 Allocation Protect: 00000004 PAGE_READWRITE0:005 !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x06ca7a7c generation 1 starts at 0x06b91000 generation 2 starts at 0x026f1000 ephemeral segment allocation context: nonesegment begin allocated size 026f0000 026f1000 02c98f8c 0x5a7f8c(5930892) 06b90000 06b91000 0732b3d0 0x79a3d0(7971792) Large object heap starts at 0x036f1000segment begin allocated size 036f0000 036f1000 03c78da0 0x587da0(5799328) Total Size: Size: 0x12ca0fc (19702012) bytes. ------------------------------ GC Heap Size: Size: 0x12ca0fc (19702012) bytes.0:005 !addressBaseAddr EndAddr1 RgnSize Type State Protect Usage ----------------------------------------------------------------------------------------------- ...26f0000 2ca2000 5b2000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE unknown [..........o.....]2ca2000 36f0000 a4e000 MEM_PRIVATE MEM_RESERVE unknown ... 说实话有经验的朋友看到这卦中信息马上就知道是怎么回事了步骤大概是这样的。 03070909 曾经实打实的分配在 SOH 上GC 触发后03070909 所在的 segment 被收缩同时对象被移走。但不知为何线程栈还保留了这个老地址 03070909而不是新地址 出现这种情况的原因大多是 C# 和 C 交互时没有把 03070909 给固定住(GCHandle.Alloc)导致GC触发对象移动之后会存在两种情况的崩溃。 C 层面的崩溃因为此时的C拿的地址不再有效了导致在非托管层崩溃。 CLR 层面的崩溃线程如果在C层面僵持托管层GC触发时会误认为这个无效的地址还是一个有效的对象进而在标记阶段导致程序崩溃。 有些朋友可能被我说懵了画个简图如下 由于这个dump属于第二种崩溃即存在僵死的线程接下来就是想办法找到这个线程。 3. 僵死的线程在哪里 如果你了解GC标记阶段的底层运作我相信你很容易找出这个答案的对只需要找到 ScanStackRoots 函数的第一个参数即可参考代码如下 void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc) {Thread* pThread NULL;while ((pThread ThreadStore::GetThreadList(pThread)) ! NULL){ScanStackRoots(pThread, fn, sc);} } 接下来上 windbg 在崩溃的线程栈上实操一下。 0:005 kb 8# ChildEBP RetAddr Args to Child 00 063ce23c 719543fc 063ce258 0a76cc88 71954260 clr!WKS::gc_heap::mark_object_simple0x12 01 063ce25c 71950b62 0a76cc88 063cec88 00000000 clr!WKS::GCHeap::Promote0xa8 02 063ce274 71951a35 063cec40 0a76cc88 00000000 clr!GcEnumObject0x37 03 063ce5d8 71950e6f 063ce920 063ce870 00000000 clr!EECodeManager::EnumGcRefs0x72b 04 063ce628 717bfaa4 063ce650 063cec40 71950da0 clr!GcStackCrawlCallBack0x139 05 063ce8f4 717bfbaa 063ce920 71950da0 063cec40 clr!Thread::StackWalkFramesEx0x92 06 063cec28 71950fa3 71950da0 063cec40 00000500 clr!Thread::StackWalkFrames0x9d 07 063cec4c 7195103e 063cec88 00000002 00000000 clr!standalone::ScanStackRoots0x430:005 dp 063cec88 L1 063cec88 08debbf80:005 !t ThreadCount: 30 UnstartedThread: 0 BackgroundThread: 29 PendingThread: 0 DeadThread: 0 Hosted Runtime: noLock ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception...30 26 3e98 08debbf8 2b220 Preemptive 00000000:00000000 0079cb88 0 MTA ... 从卦中看30号线程就是我苦苦寻找的僵死线程接下来赶紧切过去看看果然发现了C的函数xxx.Driver.xxx由于私密性我就模糊一下了哈。 0:030 ~30s eax00000000 ebx08debbf8 ecx00000000 edx00000000 esi00000000 edi00000244 eip77872aac esp0a76c9fc ebp0a76ca6c iopl0 nv up ei pl nz na pe nc cs0023 ss002b ds002b es002b fs0053 gs002b efl00000206 ntdll!NtWaitForSingleObject0xc: 77872aac c20c00 ret 0Ch 0:030 !clrstack OS Thread Id: 0x3e98 (30) Child SP IP Call Site 0a76cc18 77872aac [InlinedCallFrame: 0a76cc18] 0a76cc0c 00aa8047 DomainBoundILStubClass.IL_STUB_PInvoke(UInt32, xxx ByRef) 0a76cc18 00aa6c67 [InlinedCallFrame: 0a76cc18] xxx.Driver.xxx(UInt32, xxx ByRef) 0a76ccc0 00aa6c67 xxx.Driver.xxxFault(UInt32, System.String) ... 既然发现了C方法最后还剩一个疑问就是此时的03070909真的在非托管层吗这个可以通过搜索它的线程栈地址。 0:030 s-d poi($teb0x8) poi($teb0x4) 03070909 0a76cc88 03070909 728f5d01 68d8c642 5c654b42 .....].rB..hBKe\ 从代码中可以看到确实是在xxx.Driver.xxxFault方法里传给了C有了这些信息接下来就是告诉朋友重点关注下这个方法捋一下逻辑。 三总结 说实话这个dump分析起来还是有一定难度的它考验着你对GC标记阶段玩法的底层理解即使这位朋友是C#编程高手分析了个把星期找不出问题是能够理解的毕竟术业有专攻很开心的是这位朋友因此加了.NET高级调试训练营哈哈以dump会友。
http://www.pierceye.com/news/52377/

相关文章:

  • 难道做网站的工资都不高吗windows7PHP网站建设
  • dede网站模板怎么安装网站文案框架
  • iis网站服务器安全隐患wordpress安装插件出错
  • 创办网页短视频seo客短
  • 杭州网站优化咨询一般网站栏目结构
  • 网站建设的看法有哪些官网网站系统
  • 四平网站优化做直播app的公司
  • 绵阳住房和城市建设局网站官网wordpress 主题 模板 区别
  • 用蜗牛做logo的网站php做用户注册网站
  • 山西笑傲网站建设推广wordpress速度确实差些
  • 手机网站素材网兼职做任务的网站
  • 一些可以做翻译的网站互联网实用技术与网页制作书籍
  • 网站建设部分费用会计科目镇江佳鑫网络科技有限公司
  • 漯河建设网站app平台下载
  • 陕西省住房与城乡建设部网站好看的 网站后台模板
  • 茶社网站开发与设计的开题报告山东网站制作应用
  • 旅行社网站方案企业管理系统哪个好
  • 大业推广网站公司网站建设的视频
  • 个人博客网站建设方案wordpress原生封装app
  • 株洲网站设计外包首选百度云服务器挂网站
  • 在百度上做网站推广效果怎么样怎样在百度上做推广网站
  • 电影影视网站模板免费下载商城网站建设快速服务
  • 网页网站的区别是什么西安建设集团网站
  • 企业查询免费网站包头建设厅官方网站
  • 辽宁网站建设学校本科学院网站建设方案
  • 岳阳建设网站的公司什么是网站开发框架
  • 企业网站网址网站设计与网页制作代码大全
  • 一号建站wordpress图片本地化插件
  • 建设公司营销网站中山市有什么网站推广
  • 网站建设运营合同书整站优化seo