日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

lldb 调试 linux下 .net Core 总结及开源扩展 yinuo

發布時間:2023/12/4 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lldb 调试 linux下 .net Core 总结及开源扩展 yinuo 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相信很多朋友在跟隨微軟.net core 從windows平臺遷移至linux平臺的過程中遇到很多別扭的地方,這里我只聊聊 運行時 調試的那些事兒。

  • 首先從工具上來講Windows上的windbg肯定是運行時的首選調試工具(因為有對應版本的SOS.dll),在linux平臺運行時調試需要切換到lldb (Only lldb is supported by the SOS plugin. gdb can be used to debug the coreclr code but with no SOS support.)
    調試器的原理和功能基本一樣,但細節到某個功能的命令自然會有區別,尤其是熟練了其中1個的命令之后(比如之前在看匯編的時候是Intel格式,現在要適用AT&T格式)…

這里先總結一些個人常用的命令在 windbg下和lldb下的對比:

  • 非托管命令:

非托管命令lldbwindbg
列出當前模塊image listlmf
當前線程thread list~
當前線程棧回溯thread backtracekp
所有線程棧回溯thread backtrace all~* kp
切換線程thread select 2~2s kp
查看寄存器re rr
查看內存(8字節)memory read –size 8 –format x <address>dq <address>

LLDB同GDB的命令對比:https://lldb.llvm.org/lldb-gdb.html

  • 托管命令:

這里先介紹下自己寫的開源lldb調試.net Core擴展模塊?Yinuo
在使用lldb調試linux .net Core程序的過程中,有很多不適應的地方,比如遍歷并查看所有線程的托管棧回溯 在windbg下可以~*e !clrstack?在lldb里雖然有bt all和clrstack?但是卻只能手動切換單個線程再回溯,沒有辦法結合到一起,還有一個原因是lldb內命令輸出的內容顏色統一,不太好區分重點關注的點,比如線程回溯比較關注方法名,托管對象轉儲比較關注內部對象地址等等,lldb的好處是支持python或者c++接口,可以通過接口方式寫lldb的擴展來輔助我們調試過程,提高調試效率。
下面介紹下調試擴展 Yinuo 的加載過程:

  • 以下的軟件環境 CentOS7(x64),lldb-3.6.0,python-2.7.5

  • 首先git下載模塊?git clone https://github.com/espider/yinuo
    目錄沒有要求,但要記得,因為加載模塊的時候要知道在哪。

  • 啟動lldb 并附加被調試的進程?(lldb) attach -p PID

  • 加載Yinuo調試模塊?(lldb) command script import ~/yinuo/ynlldb.py?之前git下來的目錄里的python文件

  • 成功加載ynlldb.py后可以?help?看下當前注冊進來的命令,都以 yn_ 為前綴,加載模塊的時候會判斷當前的.net Core版本號,并自動加載對應版本的調試插件libsosplugin.so

接下來介紹下當前注冊進lldb的輔助調試命令

  • yn_heap_dump
    查看當前托管堆信息命令,以色塊和色塊的比例直觀的感受 Gen 0,1,2 LOH 在同一個堆內的比例 以及其實際大小(這里的比例按托管堆的地址空間計算,并沒有排除Free的和Gen0沒有使用的地址空間,由于比例可能相去甚遠所以有可能看不到某個堆的色塊)

  • yn_object_dump
    轉儲托管對象,可以根據類型的方法表、類型名、對象地址 進行批量或者單個轉儲,同時計算對象(按方法表或類型的話針對每1個單獨對象)所屬托管堆的位置Gen 0,1,2,LOH,并統計4類堆內的數量。
    支持選項和參數

    • –methodtable/-m?轉儲此方法表的所有對象,后跟方法表地址;

    • –type/-t?轉儲此類型名的所有對象,后跟類型名(同方法表選項互斥 2選1);

    • –offset/-o?轉儲對象的同時是否深入轉儲其內部偏移對象,后跟該對象的偏移量(目前只支持1級內部偏移)

    • –address/-a?轉儲單個對象,后跟對象地址

    • –dumpobj/-d?是否轉儲對象,默認為True,如果不轉儲則只返回對象地址;

    • –gen/-g?是否顯示對象所在的堆Gen0,1,2,LOH,默認True;

例如想要查看 類型Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1[[Microsoft.AspNetCore.Hosting.Internal.HostingApplication+Context, Microsoft.AspNetCore.Hosting]] 方法表地址?00007ff8711df620?可以這樣寫轉儲命令:

這里會對輸出內容做下顏色處理,比如我們比較關心其內部成員的Value這列,如果是地址的話會顯示成黃色,方便調試時候的快速定位。

如果想要轉儲某個對象可以這樣寫,根據對象地址:

發現對象內的某個成員比較感興趣,例如 剛剛的對象內偏移?0xe0?位置是?RawTarget

想對其進行偏移轉儲 可以這樣寫:

  • yn_thread_clrstack
    顯示某個線程或者所有線程的托管棧回溯,不指定選項?–thread/-t?的話默認顯示當前線程的托管棧回溯,?-t?跟線程index可以回溯指定線程,或者 跟?all,來批量顯示所有線程的托管棧回溯,參數?-a?可選(此為SOS命令clrstack可選參數)

這里也對輸出的內容做了顏色處理,比如IP指令指針列和CallSite是我們比較關注的,這里分別用黃色和綠色標注。

  • yn_thread_pe
    顯示某個線程或者所有線程托管異常,選項同 yn_thread_clrstack 一樣

  • yn_transfer
    此命令只用于轉移執行其他lldb命令,因為yinuo項目調試的時候會在當前目錄生成一個log文件(ynlldb.log)會把所有執行的yinuo命令及輸出寫入日志便于以后的查詢,使用例如:yn_transfer dumpheap -stat?會執行?dumpheap -stat?并把結果輸出到終端和日志文件里。

  • Yinuo?項目 License 采用 BSD,大家有興趣可以自己調整或者聯系我共同維護,實現自己的調試命令比較簡單,git項目內的 commandlist 目錄,所有自動注冊的調試命令都在這里以,自命名.py文件即可,內容例子及說明如下:



#!/usr/bin/python

# coding:utf-8

import lldb

import commandlist.ynbase as yn

from util.colorstyle import *

from util.exportcontent import *

"""這里把自定義類型注冊進來等待加載的時候自動注冊"""

def register_lldb_commands():

return [

YNTransfer()

]

"""自定義類型繼承自yn.YNCommand即可"""

class YNTransfer(yn.YNCommand):

""" transfer lldb command and exe it for log """

def __init__(self):

pass

"""這個是注冊到lldb里的命令名字"""

def name(self):

# register function name in lldb

return 'yn_transfer'

"""如果有選項的話在這里定義,基于python argparse模塊實現的 """

def options(self):

return [

]

"""描述信息"""

def description(self):

return 'Transfer lldb command for log,e.g. arguments: dumpheap -stat'

"""這里是實際命令的具體實現了"""

def run(self, options, arguments):

target = lldb.debugger.GetSelectedTarget()

if target:

if arguments:

YNTransfer.handle_command(arguments)

else:

export_content(' ? ?no arguments in yn_transfer.')

else:

export_content(' ? ?no target in current debugger.')

? ?@staticmethod

def handle_command(args):

(ci, result) = yn.run_log_command(

" " + (" ".join(args) if len(args) > 0 else ''))

success = result.Succeeded()

if success:

output = result.GetOutput()

contents = output.strip()

lines = contents.splitlines(False)

for i in range(len(lines)):

export_content(' ? ?%s' % lines[i])

else:

export_content(

' ? ?error="%s"' %

use_style_level(

important_level['high2'],

result.GetError()))

export_content(

' ? ?%s ? ' %

use_style_level(

important_level['low2'],

'-------------'))


參考文檔:

https://github.com/dotnet/coreclr/blob/master/Documentation/building/debugging-instructions.md
https://lldb.llvm.org/python-reference.html
https://github.com/llvm-mirror/lldb
https://github.com/facebook/chisel

相關文章:?

  • 快速搭建本地 .NET Core 運行時調試環境

原文地址:https://espider.github.io/NET-Core/lldb-dotnet-core-python/


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的lldb 调试 linux下 .net Core 总结及开源扩展 yinuo的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。