分类 调试 下的文章

在Visual Studio中使用调试器浏览代码时,有许多选项,包括设置断点、单步执行和使用Run-to-Cursor。在Visual Studio 2017中,引入了Run to Click,这是一种更容易调试代码的新方法——点击式风格。不再需要设置临时断点或多次执行步骤来执行代码并在所需的行上停止。现在,可以获得运行到光标(Ctrl+Shift+F10)的所有好处,而无需通过上下文菜单进行搜索,也无需将手从鼠标上移开以获得双手快捷组合。在VS中使用任何编程语言进行调试,同时包括C++、VB、C++和Python。

点击调试

当在调试器下的中断状态停止时,在鼠标悬停的代码行旁边会微妙地显示一个浅绿色的“RunExecutiontohere”标志符号。

 

将鼠标移到图示符并单击按钮。您的代码将运行并在下一次在您的代码路径中被命中时停止在该行上。

 

如果在调试代码中的数据提示来检查变量时,您可以自然地用一只手操作鼠标,这一点尤其有用。您可以快速运行以单击一行代码,检查该行上的变量,然后继续调试,同时将焦点和注意力放在该位置。运行以在同一方法、不同方法和循环内单击!

特别注意事项

记住,Run to Click将运行正在调试的应用程序的执行,直到到达该行代码为止。

  • 如果单击一行不会被命中的代码,则应用程序将执行finish。
  • 如果您单击一行代码以继续应用程序,等待其他用户输入,则一旦输入触发了该代码路径,您将中断执行运行的位置以单击。
  • 如果运行以单击某行,并且执行路径触发断点,则调试器将在路径中的任何断点处停止。当您点击“continue”(F5)时,执行将继续,并且您将在触发run单击的行上停止(就像您在该行上设置了断点一样)。

总结

运行到单击可以帮助您更快地找到要检查的代码,从而提高工作效率。

对内存转储时发生的事情有一定的了解是非常重要的。这有助于您确定要执行哪些WinDbg命令,并为您提供一些有关如何解释这些命令输出的上下文。我正在查看一个服务器的内存转储,该服务器存在性能问题。我在内存转储中根本没有看到任何运行,这意味着被转储的进程不是有问题的进程,或者,转储是从错误的机器上获取的? 是的。

我正在查看一个服务器的内存转储,该服务器存在性能问题。我在内存转储中根本没有看到任何运行,这意味着被转储的进程不是有问题的进程,或者,转储是从错误的机器上获取的(?),是的。
我查看了服务器A的PERFMON日志,发现服务器B有一个转储,问题发生在Web场中,因此可能会发生这种日志不一致。很难找到Web场中哪个服务器是出现问题的特定服务器。
你看,当你分析内存转储时,你什么也看不到,然后你开始问自己一些问题,其中一个问题是:这个转储是从有性能问题的服务器获取的吗?要找到这个结果,您需要知道服务器名,然后使用这个命令找到这个结果:

0:000> !envvar COMPUTERNAME
        COMPUTERNAME = LENOVO1-PC
WinDbg附带的帮助文档是了解WinDbg的一个很好的来源。如图所示,您可以详细阅读关于什么的内容!envvar是并且它从Exts.dll获取值,是环境变量的转储。

 

“反汇编”窗口显示与编译器所创建的指令对应的汇编代码。 如果你正在调试托管的代码,这些程序集指令对应于在实时 (JIT) 编译器,而非 Microsoft 中间语言 (MSIL) 由 Visual Studio 编译器创建所创建的本机代码。在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息。

打开窗口

  • 通过菜单栏
  • 通过源代码窗口右键菜单
  • 快捷键
    Alt+8

窗口的使用

除汇编指令外,“反汇编”窗口还可显示下列可选信息:

  • 每条指令所在的内存地址 对于本机应用程序,它是实际的内存地址。 对于 Visual Basic 或C#,它是从该函数的开头的偏移量。

  • 程序集代码派生于的源代码。

  • 代码字节,实际的计算机或 MSIL 指令的字节表示形式的即。

  • 内存地址的符号名。

  • 对应于源代码的行号。

汇编语言指令组成助记键,这是指令名称的缩写和符号的变量、 寄存器以及常量。 每个机器语言指令由一个汇编语言助记符代表还可以后跟一个或多个符号表示。程序集代码严重依赖于处理器寄存器,或者,对于托管代码,公共语言运行时注册。 可以使用反汇编窗口中的连同Register窗口中,它允许你检查寄存器内容。若要在其原始的数字格式,而不是作为程序集语言,请查看计算机代码的说明,请使用内存窗口或 select代码字节的快捷菜单中反汇编窗口。

左边距中的黄色箭头标记当前执行点。 对于本机代码中,执行点对应于 CPU 的程序计数器。 该位置显示程序中将要执行的下一条指令。

地址栏的使用

  • 1、直接输入地址

  • 2、输入函数名

寄存器是处理器(CPU)中的特殊区域,用于存储处理器需要当前处理的少量数据。 编译或解释源代码时会生成一些指令,这些指令根据需要将数据从内存移动到寄存器或反之。 相对于访问内存数据,访问寄存器数据非常快。那些允许处理器将数据保留在寄存器并多次访问的代码,比起那些需要处理器不断加载和卸载寄存器的代码执行速度快得多。 为了方便编译器将数据保存在寄存器中并实现其他优化,应避免使用全局变量而尽可能地依靠局部变量。 称以此方式编写的代码具有良好的引用局部性。 在某些语言中,如 C/C++ 中,程序员可以声明寄存器变量,它告诉编译器在所有时间尽可能地将该变量保留在寄存器中。

寄存器可分为两类:通用寄存器和专用寄存器。 通用寄存器保存用于一般操作(如将两数相加或引用数组中的元素)的数据。 专用寄存器具有特定用途和专门的意义。 堆栈指针寄存器是一个好例子,处理器利用它跟踪程序的调用堆栈。 程序员可能不会直接处理堆栈指针,但它对于程序正确运行至关重要。 没有堆栈指针,处理器在函数调用完成后将不知道返回何处。

大多数通用寄存器只保存一个数据元素。 例如单个整数、浮点数或某一数组元素。 一些新的处理器具有较大的寄存器,称为向量寄存器,可以保存一个小的数组。 由于它们可以保存较多数据,向量寄存器对于涉及数组的运算处理得非常快。 向量寄存器最初是用在昂贵的、高性能超级计算机上,但现在也用于微处理器,它们在密集的图形操作中具有很大优势。一个处理器通常有两组通用寄存器,一组针对浮点运算进行优化,一组针对整数运算进行优化。 因此,它们被称为浮点寄存器和整数寄存器。托管代码在运行时被编译为用来访问微处理器的物理寄存器的本机代码。 对于公共语言运行时或本机代码,“寄存器”窗口可以显示这些物理寄存器信息。 而对于脚本或 SQL 应用程序,“寄存器”窗口不会显示寄存器信息,因为脚本或 SQL 都是不支持寄存器概念的语言

通过“寄存器”窗口不仅可以看到寄存器的内容,还可以完成更多任务。 当本机代码处于中断模式时,可以单击寄存器内容并更改其值。 这不是可以随意做的事。 除非理解正在编辑的寄存器和它所包含的内容,草率编辑很可能导致程序崩溃或其他不良后果。

打开窗口

  • 通过菜单栏
  • 快捷键
    Alt+5

窗口的使用

查看寄存器值

在调试期间,窗口显示寄存器内容。为了减少混乱,“寄存器”窗口将寄存器组织成组,具体情况随平台和处理器类型的不同而不同。默认显示通用寄存器组。 您可以显示或隐藏寄存器组。在窗口区域右键单击弹出如下菜单

 

大家根据自己的需要在上面菜单里勾选相应的菜单就显示相应的寄存器组,去掉勾选就隐藏。

单步执行时,特别是在汇编模式下,我们可以看到被修改的寄存器值会变红。

编辑寄存器值

  1. 在“寄存器”窗口中,使用 Tab 或鼠标可以将插入点移到要更改的值的位置。 在开始键入之前,光标必须位于要覆盖的值之前。

  2. 键入新值。