4

一次k8s docker下.net程序的异常行为dump诊断 - dotnet程序故障诊断

 1 year ago
source link: https://www.cnblogs.com/dotnet-diagnostic/p/17153844.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一次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进程的内部情况 2_04.png(非生产环境,权限是允许的)

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

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

3115652-20230225100951010-92589144.png

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

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

 

3115652-20230225101129205-1560008179.png

 然后用!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

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

3115652-20230225101326255-1358988939.png

 知道了需要继续用!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看:

3115652-20230225101449778-1965566299.png

 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

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

3115652-20230225101555587-375853638.png

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

3115652-20230225101623404-860584653.png

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

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK