一:背景1. 讲故事这个案例有点特殊,以前dump分析都是和软件工程师打交道,这次和非业内人士交流,隔行如隔山,从指导dump怎么抓到问题解决,需要一个强大的耐心 。
前几天有位朋友在微信上找到我,说他们公司采购的MES系统登录的时候出现了异常,让我帮忙看一下,我在想解铃还须系铃人,怎么的也不应该找到我呀,据朋友反馈项目已经验收,那边给了回馈是网络的问题,可能没有帮他们更深入的分析吧,找我的目的应该就是验证下对方公司说的对不对。
二:WinDbg 分析1. 真的是网络问题吗在没有项目源代码和日志的情况下,最好的方式就是抓dump,一样可以找出问题所在,让朋友在程序登录卡死的时候抓了一个dump,接下来看下是不是对方工程师所说的网络问题 。
因为有卡死发生,必然有一个线程在等待什么,我们可以用 ~*e !clrstack 看下所有的线程的线程栈 。
0:000:x86> ~*e !clrstack...OS Thread Id: 0x2094 (14)Child SPIP Call Site0f94e888 0000002b [GCFrame: 0f94e888] 0f94e938 0000002b [HelperMethodFrame_1OBJ: 0f94e938] System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object)...0f94ead0 6b53d7b6 System.Threading.Tasks.Task.Wait(Int32, System.Threading.CancellationToken) [f:ddndpclrsrcBCLsystemthreadingTasksTask.cs @ 3167]0f94eae0 1468ae6b MySQL.Data.Common.Ssl.StartSSL(System.IO.Stream ByRef, System.Text.Encoding, System.String)0f94eb38 14687a55 MySql.Data.MySqlClient.NativeDriver.Open()0f94ec04 14686e63 MySql.Data.MySqlClient.Driver.Open()0f94ec28 14686ac7 MySql.Data.MySqlClient.Driver.Create(MySql.Data.MySqlClient.MySqlConnectionStringBuilder)0f94ec50 146869ec MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()0f94ec58 14686957 MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()0f94ec8c 146863e9 MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()0f94ecac 146862ca MySql.Data.MySqlClient.MySqlPool.GetConnection()0f94ece0 146817c1 MySql.Data.MySqlClient.MySqlConnection.Open()0f94ed18 0ca28753 xxx.GetMySqlConnection()...0f94efec 0ca21902 xxx.UserLogin(System.String, System.String)...0f94f4ac 6b4ae9db System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() [f:ddndpclrsrcBCLsystemthreadingthreadpool.cs @ 1161]0f94f6cc 6c500556 [DebuggerU2MCatchHandlerFrame: 0f94f6cc] ...
通过观察发现 14 号线程在一个 xxx.UserLogin 方法中,应该就是朋友点击的登录按钮的逻辑,通读一下线程栈可以看到它是在 MySql.Data.Common.Ssl.StartSSL 方法中等待,看样子是在这里超时了 。
【记一次 .NET某车零件MES系统登录异常分析】一般来说 mysql 是内网的话,不会特别去配什么 ssl 证书,这个太麻烦了,接下来验证下 mysql 是内网还是外网,可以用 !dso 查看mysql 的连接串 。
文章插图
从上面的 192.168 前缀来看果然是内网,这时候猜测走 SSL 肯定是意料之外的场景 。
2. 真的要走 SSL记得大概3-4年前在上海上班的时候,曾经有一个项目升级之后使用了nuget上的 mysql 8.0,然后项目就无法访问了,报了什么授权错误,看样子应该就是目前这个项目遇到的场景 。
接下来要验证下这个 mysql 的sdk 是 8.0 的版本吗?可以用 lm 找下 MySQL.Data 模块 。
0:014:x86> lmstartendmodule name...12b40000 12ca6000MySql_Data(deferred)...0:014:x86> lm vm MySql_DataBrowse full module liststartendmodule name12b40000 12ca6000MySql_Data(deferred)Image path: C:UsersxxxxMySql.Data.dllImage name: MySql.Data.dllBrowse all global symbolsfunctionsdataHas CLR image header, track-debug-data flag not setImage was built with /Brepro flag.Timestamp:95CE4983 (This is a reproducible build file hash, not a timestamp)CheckSum:001611FFImageSize:00166000File version:8.0.29.0Product version:8.0.29.0File flags:0 (Mask 3F)File OS:4 Unknown Win32File type:2.0 DllFile date:00000000.00000000Translations:0000.04b0Information from resource tables:CompanyName:OracleProductName:MySql.Data.CoreInternalName:MySql.Data.dllOriginalFilename: MySql.Data.dllProductVersion:8.0.29FileVersion:8.0.29.0FileDescription:MySql.DataLegalCopyright:Copyright © 2016, 2020, Oracle and/or its affiliates. All rights reserved.LegalTrademarks:Comments:ADO.NET driver for MySQL for .Net Framework and .Net Core
从上面的 Product version 来看果然是 8.0 版本,验证了我的猜想,接下来就是让朋友在连接串中加上 SslMode=None 标记,类似下面这样 。<add key="上报平台1" value=https://www.isolves.com/it/cxkf/yy/net/2023-05-08/"mysql|Database = drp; Data Source = 192.168.xx.xx; port = 3306; User Id = xxx; Password = xxx;SslMode=None" />
把结果告诉朋友之后,朋友第二天反馈问题搞定 。
推荐阅读
- 盗墓笔记|重温盗墓笔记:吴邪和齐羽到底什么关系,他们之间藏着什么阴谋
- 汪小菲|庄思敏带货麻六记,张兰直播用粤语直呼庄小姐,粉丝替汪小菲做媒
- 庄锶敏|这么快就进入角色了?庄锶敏为麻六记带货,张兰听闻开心互动
- 蔡少芬|这一次,蔡少芬给娱乐圈的女星们敲响了“警钟”
- 蔡少芬|这一次,蔡少芬给娱乐圈的女演员们敲响了“警钟”。
- 刘亦菲|刘亦菲被霸凌风波升级,网友深扒细节,被霸凌远不止这一次
- 邓超|邓超深夜发文,疑与孙俪离婚,娱记借黄景瑜离婚揭露真相
- 邓超|邓超深夜发文,疑与孙俪离婚?娱记借黄景瑜离婚事件揭露真相
- 肌肤|建议女生:洗发谨记“4不要”,头发蓬松了,“掉发”也变少了!
- 杨紫|杨紫新剧班底差?《承欢记》组训已出,网传编剧在业内名声不好!