• 重新整理 .net core 实践篇 ———— linux上排查问题实用工具 [外篇]


    前言

    介绍下面几个工具:

    Lldb
    createdump
    dotnet-dump
    dotnet-gcdump
    dotnet-symbol
    Procdump

    该文的前置篇为:

    https://www.cnblogs.com/aoximin/p/16839812.html

    献给初学者,这篇就只介绍下看下日志和lldb,毕竟东西太多了。

    正文

    我以官网的例子作为演示:https://buggyambfiles.blob.core.windows.net/bin/buggyamb_v1.1.zip

    项目地址:https://github.com/ahmetmithat/buggyamb

    我这里就已经发布可以访问了,并且用户nginx 作为转发,已经启动起来了。

    步骤在前面两篇,如果看需要发布的,可以往前面两篇看看,这里就不多复述了。

    [Unit]
    Description=BuggyAmb
    
    [Service]
    WorkingDirectory=/var/buggyamb
    ExecStart=/usr/bin/dotnet /var/buggyamb/BuggyAmb.dll
    Restart=aways
    RestartSec=10
    SyslogIdentifier=BuggyAmb
    User=root
    Environment=ASPNETCORE_ENVIRONMENT=Development
    Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
    Environment=ASPNETCORE_URLS=http://0.0.0.0:6000
    [Install]
    WantedBy=multi-user.target
    

    service 的配置如上。

    页面测试如下:

    里面分别是:

    慢、处理异常、不处理异常、崩溃、未找到页面、批处理

    崩溃情况

    这种比较好排查的,其实一般看日志就行。

    我这里点一下Crash2,让程序崩溃。 这里说明一下,上面我用的是官方例子,直接可以看代码怎么崩溃的哈。

    public class Crash2Model : PageModel
    {
    	public string quote;
    	~Crash2Model()
    	{
    		if (quote.ToString() != string.Empty)
    		{
    			quote = null;
    		}
    	}
    	public void OnGet()
    	{
    	}
    }
    

    这个可以看下。

    那么我们进行日志排查一下错误。

    journalctl -r --identifier=BuggyAmb --since "10 minute ago"
    

    告诉我们15行错误。

    -r:按反向顺序打印日志,以便首先列出最新日志。
    --identifier:请记住 SyslogIdentifier=buggyamb-identifier 测试应用程序的服务文件中的行。 (可以使用此方法强制日志仅显示适用于有问题的应用程序的条目。)
    --since:显示在指定的上一时期记录的信息。 示例: --since "10 minute ago" 或 --since "2 hour ago".
    

    journalctl 还有很多其他的功能,这里就不一一举例了。

    核心转储

    centos 默认不开启的:

    可以看下这个怎么开启的:

    https://blog.csdn.net/ProgramVAE/article/details/105921381

    #!/bin/bash
    
    #me: coredumpshell.sh
    ### Description: enable coredump and format the name of core file on centos system
    
    # enable coredump whith unlimited file-size for all users
    echo -e "\n# enable coredump whith unlimited file-size for all users\n* soft core unlimited" >> /etc/security/limits.conf
    
    # set the path of core file with permission 777 
    cd /var/buggyamb && mkdir corefile && chmod 777 corefile
    
    # format the name of core file.   
    # %% – 符号%
    # %p – 进程号
    # %u – 进程用户id
    # %g – 进程用户组id
    # %s – 生成core文件时收到的信号
    # %t – 生成core文件的时间戳(seconds since 0:00h, 1 Jan 1970)
    # %h – 主机名
    # %e – 程序文件名
    echo -e "/var/buggyamb/corefile/core-%e-%s-%u-%g-%p-%t" > /proc/sys/kernel/core_pattern
    
    # for centos7 system(update 2017.2.3 21:44)
    echo -e "/var/buggyamb/corefile/core-%e-%s-%u-%g-%p-%t" > /etc/sysctl.conf
    
    # suffix of the core file name
    echo -e "1" > /proc/sys/kernel/core_uses_pid
    
    

    运行之后就开启了。

    centos 一般用不上,我也没有去调试过,这里就不演示了,只能说有这种东西。

    使用lldb

    安装:yum install lldb

    前文提及到这个要安装lldb 3.9 以上的。

    按照这个文档来编译安装也行:

    https://github.com/dotnet/diagnostics/blob/main/documentation/lldb/linux-instructions.md

    在 lldb 中打开核心转储文件之前,请按照以下必需步骤设置符号路径,下载符号,并在打开 lldb 时自动加载 SOS :

    安装 dotnet 符号工具:

    dotnet tool install -g dotnet-symbol

    下载目标转储文件的符号:

    dotnet-symbol

    安装 SOS:

    安装 dotnet-sos 全局工具:

    dotnet tool install -g dotnet-sos

    安装 SOS:

    dotnet-sos install

    最后成功的样子:

    使用createdump:

    Createdump 会与每个 .NET Core 运行时一起自动安装。

    如 创建的ump 配置策略 文档中所述,可以设置具有环境变量的配置选项。 这些将作为参数传递给创建的ump 命令。 下面是支持的环境变量:

    COMPlus_DbgEnableMiniDump:如果设置为 1,则在终止时启用自动核心转储生成。 默认值为 0 。
    COMPlus_DbgMiniDumpType:这是将要创建的微型转储文件的类型。 此值的默认值为 2 (或枚举类型 MiniDumpWithPrivateReadWriteMemory) 。 这意味着生成的转储文件将包括 GC 堆以及捕获进程中所有现有线程的堆栈跟踪所需的信息。
    COMPlus_DbgMiniDumpName:如果设置,请用作模板来创建转储文件路径和文件名。 可以使用参数将 PID 放入名称中 %d 。 默认模板为 /tmp/coredump.%d. 通过使用此环境变量,可以配置输出目录。
    COMPlus_CreateDumpDiagnostics:如果设置为 1,则启用创建的ump 工具诊断消息 (TRACE 宏) 。 如果 createdump 不能按预期工作并且不生成内存转储文件,则此设置可能很有用。

    详细信息如下:https://github.com/dotnet/coreclr/blob/master/Documentation/botr/xplat-minidump-generation.md#configurationpolicy

    进行开启:

    然后重启,再来点击clash3进行崩溃一下。

    可以看到这里就有了。

    这里我们先转储文件符号一下:

    dotnet-symbol /tmp/coredump.9784-o /dumps/symbols/ --host-only
    

    然后进去一下:

    lldb --core /tmp/coredump.9784
    

    这个时候要加载一下dotnet 符号。

    setsymbolserver -directory /dumps/symbols/
    

    然后加载转储文件符号:

    loadsymbols
    

    这样就搞定了。

    clrsthread 查看一下线程的情况:

    这里可以看到里面有个异常是15号线程。

    切到15号线程:

    setthread 15:

    然后查看一下clrstack(调用栈信息):

    这个似乎没有告诉我们很多很有用的信息,只能告诉我们线程异常了,当然也告诉我们具体的行,可以去看下去源代码看下什么类型异常,但是有跟好用的pe。

    用pe查看下:

    pe  -- Displays and formats fields of any object derived from the Exception class at the specified address.
    

    这样就定位到具体的崩溃文件了。

    知道了崩溃是因为HttpWebRequest,希望的是能查到到底是哪个访问url造成了崩溃。

    下面这个图,证明可调用了HttpWebRequest引发的:

    使用dumpheap:dumpheap -stat -type System.Net.HttpWebRequest 查看httpwebrequest 调用栈:

    查看栈地址:

    然后是根据地址查看对象:dumpobj 00007fe0c4442f28

    这个webrequest 里面有一个是system.url 我们写程序的知道这是访问地址。

    然后继续查这个对象,上面那个value 就是地址哈。

    00007fe0c4437cf8
    

    然后可以看到url 地址:

    第一个就是了,为什么确认第一个就是,看名字。

    这样就查到了。

    先到这里吧,介绍这个lldb 是为了查看非托管栈的,如果查看托管的一般使用dotnet-dump 就好了。

    而且一般是用来分析cpu 和 内存高的地方,一般服务端错误会有日志的。

    继续后面演示cpu 和 内存高的例子,这个对服务端更有实用性。

  • 相关阅读:
    BATJ最全架构技术合集:Docker+Spring+Nginx+Netty+MySQL
    LabVIEW中使用并口
    vue3+emelenui实现前端分页功能—最简单
    辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-功能ODD定义
    5分钟自建数据库可视化平台,在线管理数据库也太方便了~
    Specializing Smaller Language Models towards Multi-Step Reasoning论文精读
    Python分支结构详解(一)——分支结构基础
    电视机@2022:降价、焦虑与机遇
    【MAPBOX基础功能】16、mapbox叠加图片图层到地图上
    Web自动化测试 —— PageObject设计模式!
  • 原文地址:https://www.cnblogs.com/aoximin/p/16839830.html