В Windbg, как я могу перечислить значения перечисления при отладке?

Обычно, enum Значения являются простыми значениями, увеличиваемыми компилятором, или задаются непосредственно в виде целочисленного литерала, поэтому значения можно легко определить или увидеть непосредственно, посмотрев на исходный файл.

Однако иногда enum значения используются для установки константы в классе, равной значению, определенному в другом месте, или результату выражения времени компиляции, которое нелегко дублировать.

Есть ли способ заставить Windbg показать мне реальную стоимость каждого enum член для тех хитрых дел?

6

Решение

Рассмотрим эту небольшую структуру:

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 (Рекурс, который вам нужно перечислить 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

Хорошо, отлично! Но как насчет этого неназванного enum? Ну, вы говорите, проверьте вывод выше, где он использует <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 и просто найти их в выводе.

9

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]