简介

高级调试过程中,与线程与线程栈是打交道特别多的。因此如何查看线程与线程栈就显得至关重要了

查看线程

!Threads

使用 !t/!Threads 命令获取所有托管线程

含义
ThreadCount 线程数量
UnstartedThread 线程创建,但未开始的
BackgroundThread 后台线程数量
PendingThread 阻塞的线程数量
DeadThread 线程已经执行完,到被线程池回收的这个过程。线程被称为Dead Thread。此时OSId会被销毁
列名 详细说明
null windbg自定义的线程Id,包含了托管线程和非托管线程。我们可以看到,0之后紧接着就是5.说明有4个非托管线程被创建
Id 托管线程Id,就是CurrentManagedThreadId
OSId 操作系统的Id,CLR团队曾经想将托管线程Id与OSId 设为多对一的关系。并未成功。现在是一对一的关系
ThreadOBJ CLR层面的Thread信息,可以用dp观察其中的内容
State CLR层面的线程状态
GC Mode CLR当前的线程状态,是抢占模式还是协作模式,主要是判断是否有操控托管堆的权限
GC Alloc Context GC会在这个上下文区间内分配对象,类似于缓冲区
Domain 当前线程所属的应用程序域,默认情况为Domain1
Lock Count 当前线程持有的托管锁个数
Apt 当前COM套件模式,分为STA与MTA
Exception 当前线程的异常信息,如果抛出异常并未处理的话

Threads命令包含了一组开关如下

  1. !t -live

只输出处于活跃状态的线程的信息

2. !t -special

额外输出所有“特殊”线程,如垃圾回收线程,线程池线程

查看非托管调用栈

k

WinDbg是非托管调试器,自带的命令k只能查看非托管调用栈。因此看不到托管部分。

会输出如下警告信息:

WARNING:Frame IP not in any known module. Following frames may be wrong.

我并没有复现,可能是版本的windbg有调整。但是红圈部分也表示了。这一段代码并没有pdb文件,所以只显示一个Entry_point

查看托管调用栈

!ClrStack

因此要查看托管代码的调用栈,要使用SOS拓展的ClrStack命令。



ClrStack命令显示了托管调用栈的所有栈帧,并有如下几个开关

  1. !Clrstack -l

    相当于local,用于显示局部变量信息

  2. !Clrstack -p

    相当于parameters将显示调用栈上每个托管代码帧的所有参数

  3. !Clrstack -a

    相当于all,把当前线程上的局部变量和参数全部显示出来

Clrstack命令如果在非托管代码线程上运行,会显示一个错误信息

!dso



有时候我们会发现有很多变量是no data. 尤其是64位程序。

我们可以辅助使用!dso命令来显示出线程调用栈的所有对象

同时查看托管/非托管调用栈

!DumpStack

Clrstack命令只输出托管代码调用栈,k命令只出书非托管调用栈。要同时输出,可以使用dumpstack命令。

使用-EE开关还表示只显示托管函数,这与ClrStack一模一样。只是多显示了方法描述符指针

可能并没有你想象的这么好用,因为输出的信息太多了。反而不利于判断。

遍历所有线程的调用栈

!EEStack

有时候,我们需要获得进程中所有托管线程的调用栈,不想重复使用0s,1s来切换线程。

我们可以使用EEStack命令,来遍历所有托管线程的调用栈,非托管线程不遍历

  1. !EEStack -short

    这个开关只输出"感兴趣"的调用栈,比如当前线程持有一个锁,线程被劫持以执行一个垃圾收集操作,线程正在执行。

  2. !EEStack -EE

    直接传递给DumpStack命令,并只显示托管代码调用栈

~*e xxx

e代表在指定线程后 追加一个指令。

比如 ~*e !clrstack 代表遍历所有托管线程的调用栈

~*e k 代表遍历所有非托管线程的调用栈

总结

.NET高级调试 - 3.8线程操作的更多相关文章

  1. Linux高级调试与优化——gdb调试命令

    番外 2019年7月26日至27日,公司邀请<软件调试>和<格蠹汇编——软件调试案例集锦>两本书的作者张银奎老师进行<Linux高级调试与优化>培训,有幸聆听张老师 ...

  2. (九) 一起学 Unix 环境高级编程 (APUE) 之 线程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  3. (十) 一起学 Unix 环境高级编程 (APUE) 之 线程控制

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  4. [Android Studio 权威教程]断点调试和高级调试

    好了开始写一个简单的调试程序,我们先来一个for循环 ? 1 2 3 4 5 6 7 8 <code class="language-java hljs ">for ( ...

  5. ###Android 断点调试和高级调试###

    转自:http://www.2cto.com/kf/201506/408358.html 有人说Android 的调试是最坑的,那我只能说是你不会用而已,我可以说Android Studio的调试是我 ...

  6. 8)Linux程序设计入门--线程操作

    )Linux程序设计入门--线程操作 前言:Linux下线程的创建 介绍在Linux下线程的创建和基本的使用. Linux下的线程是一个非常复杂的问题,由 于我对线程的学习不时很好,我在这里只是简单的 ...

  7. Android Stuido中断点调试和高级调试

    写一个简单的调试程序 import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class M ...

  8. .NET高级调试系列-Windbg调试入门篇

    Windbg是.NET高级调试领域中不可或缺的一个工具和利器,也是日常我们分析解决问题的必备.准备近期写2篇精华文章,集中给大家分享一下如果通过Windbg进行.NET高级调试. 今天我们来一篇入门的 ...

  9. winform 跨线程操作控件

    当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...

  10. 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

    在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...

随机推荐

  1. nvidia公司官方迁移学习套件 —— NVIDIA TAO Toolkit

    资料: https://blogs.nvidia.com/blog/what-is-transfer-learning/ 相关: https://developer.nvidia.com/tao-to ...

  2. 国产计算框架mindspore在gpu环境下1.3.0版本的分布式计算组件安装 ——(openmpi 和 nccl 的安装,配置,示例代码的运行)

    前文已经给出1.3.0gpu版本的编译及安装,本文在此基础上进行分布式组件的安装,前文信息参看: 国产计算框架mindspore在gpu环境下编译分支r1.3,使用suod权限成功编译并安装,成功运行 ...

  3. 如何更改Python项目中的 模块搜索第一路径

    内容承接上文: Python语言中当前工作目录(Current Working Directory, cwd)与模块搜索第一路径都是指什么??? 上文中已经解释了当前工作目录cwd与模块搜索路径的区别 ...

  4. AI 大模型时代呼唤新一代基础设施,DataOps 2.0和调度编排愈发重要

    在 AI 时代,DataOps 2.0 代表了一种全新的数据管理和操作模式,通过自动化数据管道.实时数据处理和跨团队协作,DataOps 2.0 能够加速数据分析和决策过程.它融合了人工智能和机器学习 ...

  5. SMU Spring 2023 Contest Round 2(待补

    M. Different Billing #include <map> #include <set> #include <cmath> #include <q ...

  6. 解决 Docker CE 在无根模式(rootless)下无法通过 IPv6 拉取映像的问题

    折腾一天快把我逼疯了 本来 Docker 对 IPv6 的支持就不好,再来个 rootless,雪上加霜 首先,我们要区分 Docker Engine 和 里面的 Image. 拉取映像是 Docke ...

  7. Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程

    Xinference实战指南:全面解析LLM大模型部署流程,携手Dify打造高效AI应用实践案例,加速AI项目落地进程 Xorbits Inference (Xinference) 是一个开源平台,用 ...

  8. this 之谜揭底:从浅入深理解 JavaScript 中的 this 关键字(二)

    前言 系列首发于公众号『前端进阶圈』 ,若不想错过更多精彩内容,请"星标"一下,敬请关注公众号最新消息. this 之谜揭底:从浅入深理解 JavaScript 中的 this 关 ...

  9. stm32g070 不同channel区别

    1. TIM 2.UART

  10. 004.MinIO-DirectPV分布式存储部署

    MinIO部署介绍 部署概述 Kubernetes hostpath.local和本地静态配置都存在需要事先在node节点准备好可用的块存储或文件系统,例如对插入的硬盘,或者磁盘阵列做分区格式化,文件 ...