如何在WinDbg中的另一个别名中使用别名解释器?

问题描述 投票:0回答:1

我有一堆别名用于访问代码中的全局调试变量,它们看起来像这样:

aS _dbg_log_last "dx mymodule!g_dbg_variable_with_a_long_name->logger.log_buffer[mymodule!g_dbg_variable_with_a_long_name->logger.size - 1]"

我显然不喜欢最后一个重复的内容,所以我尝试将其重构为以下内容:

aS _dbg_log "mymodule!g_dbg_variable_with_a_long_name->logger"
aS _dbg_log_last "dx ${_dbg_log} .log_buffer[${_dbg_log}.size - 1]"

如果我复制

_dbg_log_last
别名的内容并手动运行它,一切都会正常。但如果我真的尝试调用它,我会收到错误:

错误:{_dbg_log} 处出现意外标记...

所以看起来它在执行别名时吞下了

$
字符。我也尝试过取消引用其中一个或两个别名,使用
as
而不是
aS
,向别名解释器添加
/f
和其他标志,用
$
\$
转义
$$
,没有任何效果。

最小重现:

aS _foo "1"
aS _bar "dx ${_foo} ,x"

dx ${_foo} ,x
_bar

预期:

1 ,x : 0x1
1 ,x : 0x1

实际:

1 ,x : 0x1
Error: Unexpected token at '{_foo} ,x'
alias windbg
1个回答
0
投票

我无法直接回答你的问题,我推测问题在于你正在使用“旧”alias方案和新的

dx
(对象模型表达式)。

只使用新的 dx 命令会更容易。这是一个简单的重现示例:

#include <iostream>

typedef struct Logger
{
    unsigned fooLogger;
    unsigned barLogger;
    unsigned size;
    const char* log_buffer[1];
} Logger;

typedef struct MyStruct
{
    unsigned foo;
    unsigned bar;
    Logger logger;
} MyStruct;

MyStruct* g_dbg_variable_with_a_long_name;

void DumpStruct()
{
    std::printf("foo: 0x%08x\n", g_dbg_variable_with_a_long_name->foo);
    std::printf("bar: 0x%08x\n", g_dbg_variable_with_a_long_name->bar);
    std::printf("fooLogger: 0x%08x\n", g_dbg_variable_with_a_long_name->logger.fooLogger);
    std::printf("barLogger: 0x%08x\n", g_dbg_variable_with_a_long_name->logger.barLogger);
    std::printf("size: %d\n", g_dbg_variable_with_a_long_name->logger.size);
    for (unsigned i = 0; i < g_dbg_variable_with_a_long_name->logger.size; i++)
    {
        std::printf("log_buffer[%d]: %s\n", i, g_dbg_variable_with_a_long_name->logger.log_buffer[i]);
    }
}

int main(void)
{
    MyStruct myStruct;
    myStruct.foo = 0x12345678;
    myStruct.bar = 0xdeadbeef;
    myStruct.logger.fooLogger = 0x11111111;
    myStruct.logger.barLogger = 0x22222222;

    myStruct.logger.size = 2;
    myStruct.logger.log_buffer[0] = "Hello";
    myStruct.logger.log_buffer[1] = "World";

    g_dbg_variable_with_a_long_name = &myStruct;

    DumpStruct();

    return 0;
}

DumpStruct
上设置一个 BP(这个想法是有一个已知结构被初始化的点;是的,它是用局部初始化的全局......)。

bp test!DumpStruct

现在,使用

dx
分配您想要的内容(而不是通过
sa
别名):

dx @$_dbg_log = test!g_dbg_variable_with_a_long_name->logger
dx @$_dbg_log_last = @$_dbg_log.log_buffer[@$_dbg_log.size - 1]

(旁注:这些分配在技术上是对调试器寄存器进行的,您可以使用

dx @$vars
获取它们;只是不要忘记它们带有
@$
前缀,这可能是您的情况下 dx 命令的混乱根源) .

输出:

0:000> dx @$vars
@$vars                
    _dbg_log         [Type: Logger]
    _dbg_log_last    : 0x7ff7af61aca8 : "World" [Type: char *]

0:000> dx @$_dbg_log
@$_dbg_log                 [Type: Logger]
    [+0x000] fooLogger        : 0x11111111 [Type: unsigned int]
    [+0x004] barLogger        : 0x22222222 [Type: unsigned int]
    [+0x008] size             : 0x2 [Type: unsigned int]
    [+0x010] log_buffer       [Type: char * [1]]

0:000> dx @$_dbg_log_last
@$_dbg_log_last                 : 0x7ff7af61aca8 : "World" [Type: char *]
    87 'W' [Type: char]

$$ same as:

0:000> dx @$_dbg_log_last,s
@$_dbg_log_last,s                 : 0x7ff7af61aca8 : "World" [Type: char *]
    87 'W' [Type: char]

你也可以做一些不同的事情:

0:000> dx @$first = 0
@$first = 0      : 0

0:000> dx @$last = @$_dbg_log.size - 1
@$last = @$_dbg_log.size - 1 : 0x1

0:000> dx @$_dbg_log.log_buffer[@$first]
@$_dbg_log.log_buffer[@$first]                 : 0x7ff7af61aca0 : "Hello" [Type: char *]
    72 'H' [Type: char]

0:000> dx @$_dbg_log.log_buffer[@$last]
@$_dbg_log.log_buffer[@$last]                 : 0x7ff7af61aca8 : "World" [Type: char *]
    87 'W' [Type: char]

或一次性记录所有内容:

(注意:由于缓冲区仅用一个元素声明,因此我们需要告诉 Windbg 表有多少元素;这是无法传递变量的少数情况之一......我们需要在这里传递一个标量)

0:000> dx *(char* (*)[2])@$_dbg_log.log_buffer
*(char* (*)[2])@$_dbg_log.log_buffer                 [Type: char * [2]]
    [0]              : 0x7ff7af61aca0 : "Hello" [Type: char *]
    [1]              : 0x7ff7af61aca8 : "World" [Type: char *]

$$ !!! DOES NOT WORK !!! :(

0:000> dx *(char* (*)[@$_dbg_log.size])@$_dbg_log.log_buffer
Error: Unexpected token at '@$_dbg_log.size])@$_dbg_log.log_buffer'
© www.soinside.com 2019 - 2024. All rights reserved.