• 一次k8s docker下.net程序的异常行为dump诊断


    背景

    昨天,一位朋友找到我寻求帮助。他的项目需要调用一个第三方项目的webAPI。这个webAPI本身可从header, query string中取相关信息,但同事发现他在调用时,无法按期望的那样从query string中传参数给到第三方webAPI (webAPI仿佛忽略了从query string过来的信息),朋友不知道是这个webAPI的问题,还是自己调用代码的问题了。。

    由于这个webAPI service是他们公司内部的某team的项目,所以朋友虽然可以看到源码,但他并不能快速确定原因, 维护项目的人又不好找。通过webAPI service代码他自己找到了可疑的原因是webAPI中的这个方法有可能阻挡了他期望的webAPI行为: Instance.EnableFallback() (公司隐私,改了名), 但他无法确定这个方法在实际运行的时候的具体返回值。

    听了朋友介绍,我能想到的一个方法是看一下他们公司的这个第三方的service进程的内部情况 (非生产环境,权限是允许的)

    分析

    通过kubectl exec -it [namespace:pod] /bin/bash,我们成功进入了service的pod里。虽然是非生产环境,我们也尽量别打扰人家干活  那么…就选择dump一下运行的dotnet进程喽

    由于这次的任务是观察托管环境的某个内存位置的值,我选择了用dotnet-dump

     

    然后dotnet-dump analyze core_123 开始分析。

    我们想要的是 Instance.EnableFallback 的返回值,而我的朋友已经知道这个Instance的type,所以用dumpheap -type找一下这个instance在哪里:

     

     

     然后用!do一下instance具体内容:

    复制代码
    1 > do 796f3840d080
    2 Name:        XXX.Common.XXX.XXXInstance
    3 MethodTable: 00007970d459d3a8
    4 EEClass:     00007970d45a4fc0
    5 Size:        80(0x50) bytes
    6 File:        /app/XXX.dll
    7 Fields:
    8               MT    Field   Offset                 Type VT     Attr            Value Name
    9 00007970d459d9e8  4000016       10 ...XXX]]  0 instance 0000796f3840d130 _evs
    复制代码

    根据简化和隐藏敏感信息后的代码:

     

     知道了需要继续用!do 看这个0000796f3840d130:

    复制代码
     1 > do 0000796f3840d130
     2 Name:        System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib],[XXX.Common.XXX.XXXEnv, XXX]]
     3 MethodTable: 00007970d459d718
     4 EEClass:     00007970ce610c00
     5 Size:        72(0x48) bytes
     6 File:        /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.32/System.Private.CoreLib.dll
     7 Fields:
     8               MT    Field   Offset                 Type VT     Attr            Value Name
     9 00007970ce636448  4001aec        8       System.Int32[]  0 instance 0000796f384143a8 _buckets
    10 00007970ce636250  4001aed       10 ...ivate.CoreLib]][]  0 instance 0000796f384143d0 _entries
    11 00007970ce5fa0e8  4001aee       30         System.Int32  1 instance                1 _count
    复制代码

    大家如果了解.net Dictionary类型的实现,就知道目前这个dictionary是1size且具体的item值可以直接用!dp看:

     

     Dictionary里的_entries是个数组,item类型是value type,所以是inlined memory, 所以直接看0000796f38412948, 因为他是数组中第0个元素里的key-value pair里的value(XXXEnv instance的地址)。

    复制代码
    1 > do 0000796f38412948
    2 Name:        XXX.Common.XXXEnv
    3 MethodTable: 00007970d459e700
    4 EEClass:     00007970d45a5888
    5 Size:        56(0x38) bytes
    6 File:        /app/XXX.dll
    7 Fields:
    8               MT    Field   Offset                 Type VT     Attr            Value Name
    9 00007970d340a988  400000a        8 ....Config.XXXConfig  0 instance 0000796f382898f0 _toggleConfig
    复制代码

    最后看那个_toggleConfigInstance.EnableFallback()里面一通调用最终会读它的内容,简化代码如下:

     

     所以继续!do看一下这个_toggleConfig:

     

     至此原因确定,怀疑的这个方法在当前这个webAPI service下会返回false.

    后记

    也许有朋友会问,直接dump type是XXXConfig的instance不就行了。是的,不过在这个dump文件中,我发现了不止一个active的XXXConfig instance, 也就是说不止一处会用到这个不唯一的XXXConfig, 而我需要明确Instance.EnableFallback最终的返回,所以需要耐心探索哈 

    总结

    我的朋友知道了他想确定的Instance.EnableFallback在第三方service运行的时候的真实值之后,也明确了他那边的应对这个webAPI的调用方式了。

    这次诊断的问题虽不是cpu过高、内存泄漏这类资源问题,但还是用上了与排查资源泄漏相同的底层调试诊断技术来解决。最后我的朋友很高兴,吃了个定心丸

  • 相关阅读:
    半监督学习在恶意软件流量检测中的应用
    协同过滤算法
    2021 XV6 4:traps
    在GPU上运行MATLAB程序
    STL 容器操作集合
    qlib智能量化里的“因子分析“,“多空分析”
    JMeter 做接口性能测试,YYDS!
    聚酰胺-胺(PAMAM)树形聚合物-硫化铋复合纳米粒子|硫化铋修饰Gd‑DTPA‑OA配体|科研实验用
    【MYSQL】表的综合查询
    FreeSWITCH 1.10.10 简单图形化界面8 - 讯时FXO网关SIP注册公网IPPBX落地
  • 原文地址:https://www.cnblogs.com/dotnet-diagnostic/p/17153844.html