前言
介紹下面幾個工具:
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 <path_of_dump_file>
安裝 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 和 內存高的例子,這個對服務端更有實用性。