windbg :查看局部变量值

发布时间:2024年01月24日

查看变量有以下几种常用方式:

仍以我们上篇 : 《windbg : x 命令》中的代码作为示例来讲解使用。

源码:

#include <iostream>

using namespace std;

struct JKGirl{
    std::string name;
    int age;
    
    friend ostream& operator <<(ostream& o,const JKGirl& that)
    {
        return o << that.name << " is " << that.age << " years old.";
    }
};


int factorical(unsigned int n){
    
    static int result = 1;
    
    if(n <= 0 ) return result; // 递归结束条件
    
    result *= n;    // 算子
    
    return factorical(--n) ; // 递归
}

int main()
{
    
    int num = 20;
    double f = 30.25;
    
    int result =  factorical(3);
    
    cout << result << endl;
    
    
    JKGirl girl = {"Anna",18};
    cout << girl << endl;
    
    
    return 0;
}


一、通过windbg “局部变量”窗口查看

“局部变量”窗口显示有关当前范围内所有局部变量的信息。

若要打开或切换到“局部变量”窗口,请在“WinDbg”窗口中的“ 视图 ”菜单上,选择“ 局部变量”。 (还可以按 Alt+3 或选择工具栏上的 “局部变量 ”按钮。Alt+SHIFT+3 关闭“局部变量”窗口。)

在这里插入图片描述
忽略左侧乱七八糟的加密字符串,这是博主电脑加密,导致源码显示乱码的问题。(摸鱼被你们发现了~)

在这里插入图片描述

二、通过在“调试器命令”窗口中输入 dv 命令或 dt 命令来查看局部变量和参数

0:000> dv
            num = 0n20
           girl = struct JKGirl
              f = 30.25
         result = 0n6

通过dv指令,查看当前栈上的所有局部变量的值
通过dt 变量指令,查看指定局部变量的数据类型

dv指令貌似直接给我们显示了当前栈上的部分局部变量的信息,为什么是部分呢?这个结构体变量 girl = struct JKGirl 它只告诉了我这是一个结构体,没具体显示每个成员的值啊,咋整?

结构体变量值的查询

我们采用如下指令可以具体查询结构体变量的值:
先通过dt指令获取结构体变量的地址

0:000> dt girl
Local var @ 0xe32d6ffad8 Type JKGirl
   +0x000 name             : std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x028 age              : 0n18

现在我们拿到了girl变量的地址 0xe32d6ffad8,注意往下看,同时显示了girl中两个成员变量的地址偏移。
girl.name 的偏移是 0x000,首地址即首个成员变量的地址
girl.age 的偏移是 0x028,那么girl.age 可以通过地址0xe32d6ffad8+0x028进行访问

拿到了变量的地址,那这件事就好办了。

我们通过dx指令来访问目标地址。

0:000> dx -r1 (*((WD01!JKGirl *)0xe32d6ffad8))
(*((WD01!JKGirl *)0xe32d6ffad8))                 [Type: JKGirl]
    [+0x000] name             : "Anna" [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
    [+0x028] age              : 18 [Type: int]

这里我们使用了 dx -r1 递归显示变量girl的所有成员。
比较看看,如果使用 dx -r2会怎样?

0:000> dx -r2 (*((WD01!JKGirl *)0xe32d6ffad8))
(*((WD01!JKGirl *)0xe32d6ffad8))                 [Type: JKGirl]
    [+0x000] name             : "Anna" [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
        [<Raw View>]     [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
        [size]           : 0x4 [Type: unsigned __int64]
        [capacity]       : 0xf [Type: unsigned __int64]
        [allocator]      : allocator [Type: std::_Compressed_pair<std::allocator<char>,std::_String_val<std::_Simple_types<char> >,1>]
        [0]              : 65 'A' [Type: char]
        [1]              : 110 'n' [Type: char]
        [2]              : 110 'n' [Type: char]
        [3]              : 97 'a' [Type: char]
    [+0x028] age              : 18 [Type: int]

简单说一下,dx -r1是简单打印模式; dx -r[n>1]是详细模式。

如果需要查看指定结构体成员的值,可以通过 dx 变量.成员变量的方式 来查看,如下示例:

0:000> dx girl.name
girl.name                 : "Anna" [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
    [<Raw View>]     [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
    [size]           : 0x4 [Type: unsigned __int64]
    [capacity]       : 0xf [Type: unsigned __int64]
    [allocator]      : allocator [Type: std::_Compressed_pair<std::allocator<char>,std::_String_val<std::_Simple_types<char> >,1>]
    [0]              : 65 'A' [Type: char]
    [1]              : 110 'n' [Type: char]
    [2]              : 110 'n' [Type: char]
    [3]              : 97 'a' [Type: char]
0:000> dx girl.age
girl.age         : 18 [Type: int]

ok,到这里就解决了我们在调试过程中查看结构体成员变量的难点


扩展讲讲 dx 指令

windbg中,dx(display expression)是一个非常强大和灵活的命令,用于显示和解析复杂的数据结构和表达式。使用dx命令,可以直接在命令行中执行表达式,并以易于阅读的方式显示结果。

dx命令的基本语法为:

dx [options] expression

以下是dx命令的一些常用选项:

  • /t:指定要显示的数据类型,例如/t MyStruct
  • /r:以递归方式显示对象的所有成员,包括嵌套结构体和指针。
  • /v:显示详细的调试信息,包括成员的偏移量和大小。
  • /g:显示全局符号,例如全局变量和函数。
  • /v:显示详细的调试信息,包括成员的偏移量和大小。
  • /f:根据指定的格式化字符串显示结果。

下面是一些例子,以演示dx命令的用法:

  1. 查看一个变量的值:
dx myVar
  1. 查看一个结构体的成员:
dx myStruct.Member
  1. 以递归方式查看一个结构体的所有成员:
dx /r myStruct
  1. 使用格式化字符串查看一个结构体的成员和其值:
dx /f "Member1: %i, Member2: %s" myStruct
  1. 查看一个数组变量的元素:
dx myArray[0]
  1. 查看一个指针变量的指向的结构体的成员:
dx myPtr->Member

需要注意的是,在使用dx命令之前,需要先加载符号信息,以便能够正确解析表达式和数据类型。可以使用命令.symfix.reload /f来加载符号信息。


文章来源:https://blog.csdn.net/weixin_39568531/article/details/135822245
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。