来自 as /c 的 Windbg .printf 字符串别名
Windbg .printf string alias from as /c
希望这是一个简单的问题,但是如果我将别名 a1
定义为带有 as /x a1 1+1
的表达式 1+1
然后我可以通过 .echo a1
或 .printf "a1 = %d", a1
.
如果我将别名 a2
定义为带有 as /c a2 dv /t this
的 CommandString
,是否可以对 .printf
执行相同的操作?
我当然可以 .echo
,但是尝试 .printf "a2 = %ma", a2
会出现 Couldn't resolve error at
错误,例如:
.printf "a2 = %ma", a2
class Blah:Blah:Blah * this = 0x00000000194dacf0
= Couldn't resolve error at 'class Blah::Blah::Blah * this = 0x00000000194dacf0
'
如果用as /c a2 .printf "hello"
定义a2
也是一样的。我找不到 .printf
用于显示字符串别名的示例,否则我只能抄袭...我觉得这很奇怪,除非我遗漏了一些明显的东西。
您似乎对别名的工作方式有点困惑(相信我,这是完全正常的,它们相当不直观!我花了一些时间来了解它们的工作方式,但我仍然不是 100% 确定,但让我来回答一下你的问题!)
首先,不要把别名当成"variables"!它们不是保留某些值的符号名称。它们更像是宏(如果已分配,则由预处理器替换)。
要真正注意到差异,请更加注意 .printf "a1 = %d", a1
的工作方式。我不知道我们是否有不同的版本,或者它是否与关于 "entering a new block" 的奇怪别名解释规则有关,但是,这就是我所看到的:
0:000> as /x a1 1+1
0:000> .echo a1
0x2
0:000> .printf "a1 = %d", a1
0x2 = 2
请注意,它不是在说 a1 = 2
,而是在引号内替换 a1
(或者更像是在它看到它的任何地方)。就好像它在执行命令之前在做一个字符串查找和替换!
因此,在您的第二个示例中,它再次在 printf 的格式说明符引号内和之后(当它用作参数时)替换该命令的输出。如果该命令输出不像 printf 参数列表,它会变得混乱!
别名的经验法则是我认为上面的粗体句。将它们作为宏,由预处理器替换。
0:000> dv /t this
class Student * this = 0x000000c5`d6f6f910
0:000> as /c foo dv /t this
0:000> al
Alias Value
------- -------
foo class Student * this = 0x000000c5`d6f6f910
0:000> .printf "${foo}"
class Student * this = 0x000000c5`d6f6f910
你接受了这个,但我打算在评论中问你这个问题而不是编辑答案
我回答了问题,但你为什么要尝试使用 %ma ??它应该在目标虚拟地址 space 中打印一个 ascii 字符串,例如
0:000> .printf "%ma\n" , poi(poi(this)+8)
dave
编辑别名解释器的用法
0:000> .printf "to check if an alias is defined use ${/v:foo} ${/n:foo} == 1 \n"
to check if an alias is defined use ${/v:foo} foo == 1
0:000> .printf "to expand an alias ${/n:foo} use ${/v:foo} == ${foo} "
to expand an alias foo use ${/v:foo} == class Student * this = 0x000000c5`d6f6f910
希望这是一个简单的问题,但是如果我将别名 a1
定义为带有 as /x a1 1+1
的表达式 1+1
然后我可以通过 .echo a1
或 .printf "a1 = %d", a1
.
如果我将别名 a2
定义为带有 as /c a2 dv /t this
的 CommandString
,是否可以对 .printf
执行相同的操作?
我当然可以 .echo
,但是尝试 .printf "a2 = %ma", a2
会出现 Couldn't resolve error at
错误,例如:
.printf "a2 = %ma", a2
class Blah:Blah:Blah * this = 0x00000000194dacf0
= Couldn't resolve error at 'class Blah::Blah::Blah * this = 0x00000000194dacf0
'
如果用as /c a2 .printf "hello"
定义a2
也是一样的。我找不到 .printf
用于显示字符串别名的示例,否则我只能抄袭...我觉得这很奇怪,除非我遗漏了一些明显的东西。
您似乎对别名的工作方式有点困惑(相信我,这是完全正常的,它们相当不直观!我花了一些时间来了解它们的工作方式,但我仍然不是 100% 确定,但让我来回答一下你的问题!)
首先,不要把别名当成"variables"!它们不是保留某些值的符号名称。它们更像是宏(如果已分配,则由预处理器替换)。
要真正注意到差异,请更加注意 .printf "a1 = %d", a1
的工作方式。我不知道我们是否有不同的版本,或者它是否与关于 "entering a new block" 的奇怪别名解释规则有关,但是,这就是我所看到的:
0:000> as /x a1 1+1
0:000> .echo a1
0x2
0:000> .printf "a1 = %d", a1
0x2 = 2
请注意,它不是在说 a1 = 2
,而是在引号内替换 a1
(或者更像是在它看到它的任何地方)。就好像它在执行命令之前在做一个字符串查找和替换!
因此,在您的第二个示例中,它再次在 printf 的格式说明符引号内和之后(当它用作参数时)替换该命令的输出。如果该命令输出不像 printf 参数列表,它会变得混乱!
别名的经验法则是我认为上面的粗体句。将它们作为宏,由预处理器替换。
0:000> dv /t this
class Student * this = 0x000000c5`d6f6f910
0:000> as /c foo dv /t this
0:000> al
Alias Value
------- -------
foo class Student * this = 0x000000c5`d6f6f910
0:000> .printf "${foo}"
class Student * this = 0x000000c5`d6f6f910
你接受了这个,但我打算在评论中问你这个问题而不是编辑答案
我回答了问题,但你为什么要尝试使用 %ma ??它应该在目标虚拟地址 space 中打印一个 ascii 字符串,例如
0:000> .printf "%ma\n" , poi(poi(this)+8)
dave
编辑别名解释器的用法
0:000> .printf "to check if an alias is defined use ${/v:foo} ${/n:foo} == 1 \n"
to check if an alias is defined use ${/v:foo} foo == 1
0:000> .printf "to expand an alias ${/n:foo} use ${/v:foo} == ${foo} "
to expand an alias foo use ${/v:foo} == class Student * this = 0x000000c5`d6f6f910