通常,enum
值是简单的编译器递增值或直接设置为整数文字,因此可以通过查看源文件轻松推断或直接看到这些值。
但是,有时enum
值用于将类内常量设置为等于在别处定义的值,或者用于不易复制的编译时表达式的结果。
有没有办法让Windbg向我展示每个enum
成员对于那些棘手案件的实际价值?
答案 0 :(得分:9)
考虑这个小结构:
struct foo
{
enum enum1
{
enum1_val1_ = 5,
enum1_val2_,
};
enum enum2
{
enum2_val1_ = 0x0001,
enum2_val2_ = 0x0010,
};
enum
{
// assume these come from complicated compile-time expressions
some_class_constant_ = 86,
another_one_ = 99,
};
};
最快的方法是使用dt
命令,使用开关-r
(recurse,您需要列出enum
成员)和-v
(详细,你需要列出enum
:
0:000> dt -r -v foo
LangTestingD!foo
struct foo, 3 elements, 0x1 bytes
Enum enum1, 2 total enums
enum1_val1_ = 0n5
enum1_val2_ = 0n6
Enum enum2, 2 total enums
enum2_val1_ = 0n1
enum2_val2_ = 0n16
Enum <unnamed-tag>, 2 total enums
some_class_constant_ = 0n86
another_one_ = 0n99
你可以看到它列出了每个枚举的值,甚至是未命名的值。多个未命名的枚举都将正确列出。
dt -r -v foo
的问题在于它列出了foo
的每个成员:所有数据成员,所有功能成员,所有枚举,和它试图递归到每个成员一个并列出其成员。如果foo
是一个复杂的类,它很容易通过继承获得,那么输出将是巨大的,并且很难找到你正在寻找的枚举。
所以接下来的选择是告诉dt
你需要哪个枚举,具体来说:
0:000> dt foo::enum1
LangTestingD!foo::enum1
enum1_val1_ = 0n5
enum1_val2_ = 0n6
好的,太棒了!但那个未命名的枚举怎么样?好吧,你说,看看上面的输出,它使用<unnamed-tag>
。也许我们可以使用它。
0:000> dt foo::<unnamed-tag>
Couldn't resolve error at 'foo::<unnamed-tag>'
它实际上会起作用,但你需要使用一些额外的开关。当您将-n
(以下参数是名称)和-y
(将下一个参数作为名称前缀匹配)组合时,那么它有点有效:
0:000> dt -n -y foo::<unnamed-tag>
LangTestingD!foo::<unnamed-tag>
some_class_constant_ = 0n86
但是,仅列出第一个值。更糟糕的是,如果有多个未命名的枚举,则只列出第一个值的第一个值。这通常就足够了,因为多个未命名的枚举并不常见,但如果您绝对需要它们,则必须使用-r -v
并在输出中找到它们。