Windows WINDBG:查看未命名命名空间中的变量值

Windows WINDBG:查看未命名命名空间中的变量值,windows,debugging,visual-c++,windbg,Windows,Debugging,Visual C++,Windbg,一旦您闯入Windbg,是否有什么技巧可以查看未命名名称空间中的变量值?我这样定位变量: 0:000> x mod!ns::*myvar* 70f7afc6 mod!ns::`anonymous namespace'::`dynamic initializer for 'myvar'' (void) 717bb799 mod!ns::`anonymous namespace'::`dynamic atexit destructor for 'myvar'

一旦您闯入Windbg,是否有什么技巧可以查看未命名名称空间中的变量值?我这样定位变量:

0:000> x mod!ns::*myvar*
70f7afc6          mod!ns::`anonymous namespace'::`dynamic initializer for 'myvar'' (void)
717bb799          mod!ns::`anonymous namespace'::`dynamic atexit destructor for 'myvar'' (void)
71a00718          mod!ns::`anonymous namespace'::myvar = <no type information>
0:000>x模!ns::*myvar*
70f7afc6模块!ns::`anonymous namespace'::`myvar''的动态初始值设定项(void)
717bb799模块!ns::`anonymous namespace'::`myvar''的动态atexit析构函数(void)
71a00718国防部!ns::`匿名名称空间'::myvar=
myvar
基本上是一个
std::map
并且有一个调试器可视化工具(natvis)可供使用,以便
??myvar
应该显示一些可用的内容。然而,由于匿名名称空间介于两者之间,我似乎无法找到在
myvar
中显示值的正确语法

有什么想法吗?

从历史上看,windbg在实现这些奇特的显示方面落后了一两英里

也就是说你的名字空间是嵌套的吗

我假设是,因为模块mod之后有一个ns!ns::

如果不是这样的话,x mymap将产生一个可点击的dml链接 如果类型是嵌套的,它将正确显示该类型。windbg将吐出没有可用的类型信息

在这种情况下,您可以使用mod!标准::地图………xxx…

下面是在windbg下编译和执行的人工源代码,演示了一些可能性

第一个文件的源此文件包含一个未命名的ns和一个已命名的嵌套未命名的ns,并且还引用另一个包含匿名命名空间的文件

#include "anonall.h"
namespace {
    map<char, const char*> mymap;
    const char *Greek_Alphabets[ALLOCSIZ] = { "Alp","Bet","Gam","Del","Eps" };
}
namespace ns {
    namespace {
        map<char, const char*> mymap;
        const char *Greek_Alphabets[ALLOCSIZ]={ 
        "Alpha","Beta","Gamma","Delta","Epsilon" };
    }
}
void anonnsptwo(void);
void anonnsptre(void) {
    cout << "\nfrom Anonymous NS Map in " << __FILE__ << " " << __LINE__ << "\n\n";
    for (int i = 0; i < ALLOCSIZ; i++) {
        mymap.insert(pair<char, const char*>(char('M' + i), Greek_Alphabets[i]));
    }
    map<char, const char*>::iterator iter = mymap.begin();
    for (iter; iter != mymap.end(); iter++)
        cout << iter->first << " = " << iter->second << "\n";
}
int main(void) {
    anonnsptre();
    cout << "\nfrom Anonymous NS Map in " << __FILE__ << " " << __LINE__ << "\n\n";
    for (int i = 0; i < ALLOCSIZ; i++) {
        ns::mymap.insert(pair<char, const char*>(char('A'+i),ns::Greek_Alphabets[i]));
    }
    map<char, const char*>::iterator iter = ns::mymap.begin();
    for (iter; iter != ns::mymap.end(); iter++)
        cout << iter->first << " = " << iter->second << "\n";
    anonnsptwo();
    return 0;
}
执行二进制文件

anonone.exe
from Anonymous NS Map in anonone.cpp 15

M = Alp
N = Bet
O = Gam
P = Del
Q = Eps

from Anonymous NS Map in anonone.cpp 25

A = Alpha
B = Beta
C = Gamma
D = Delta
E = Epsilon

from Anonymous Namespace Map in anontwo.cpp

V = Kappa
W = Iota
X = Theta
Y = Eta
Z = Zeta
使用cdb仅显示结果,无需用户干预

如果使用windbg而不是cdb,则结果为x**我的地图将是可点击的链接

注意size=5,注意另外两个没有类型信息的匿名MyMap
(您关于如何打印这些mymaps的问题如下)

在第一个文件返回时设置断点(程序结束)

grep-in ret.*anonone.cpp
33:返回0
cdb-c“。行;bu`anonone.cpp:33`\'x**mymap*\“g;q”anonone.exe e

cdb-c“。行;bu`anonone.cpp:33`\'x**mymap*\“g;q”anonone.exe
Microsoft(R)Windows调试器版本10.0.16299.15 X86
0:000>cdb:读取初始命令行;bu`anonone.cpp:33`“x*!*mymap*”;Gq'
斯尼普======================
0118b938无!mymap={size=0x5}
01175198无!mymap$初始值设定项$=0x0110100
011742c0无`匿名命名空间“::`mymap“”的动态atexit析构函数(void)
01101040无`匿名命名空间“::`mymap“”的动态初始值设定项(无效)
011742e0无!ns::`anonymous namespace'::`mymap''的动态atexit析构函数(void)
011742d0无!ns::`anonymous namespace'::`mymap''的动态atexit析构函数(void)
0110100无!ns::`anonymous namespace'::`mymap'的动态初始值设定项(void)
01101060无!ns::`anonymous namespace'::`mymap'的动态初始值设定项(void)
0118b930无!ns::`匿名命名空间'::mymap=
0118b960无!ns::`匿名命名空间'::mymap=
退出:
现在可以将mymap@0x0118b960和0x0118b930的地址转换为std::map
(do x anonone!std::map hit tab查找类型信息,将其设置为指针并粘贴地址,然后使用dx表达式计算器获取显示)

这就像是dx(anonone!std:map……xx..yy..zz*)0x0118b960

ntdll!LdrpDoDebuggerBreak+0x2c:
771d05a6 cc              int     3
Processing initial command '$$>a< displayanon.txt'
0:000> $$>a< displayanon.txt
ModLoad: 6b450000 6b453000   C:\Windows\system32\api-ms-win-core-synch-l1-2-0.DLL
00d6b938          anonone!mymap = { size=0x5 }
00d55198          anonone!mymap$initializer$ = 0x00ce1040
00d542c0          anonone!`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
00ce1040          anonone!`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
00d542e0          anonone!ns::`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
00d542d0          anonone!ns::`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
00ce1080          anonone!ns::`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
00ce1060          anonone!ns::`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
00d6b930          anonone!ns::`anonymous namespace'::mymap = <no type information>
00d6b960          anonone!ns::`anonymous namespace'::mymap = <no type information>


this is the type which you can get by using x {mod}!{std::map {wildcard}}

class std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > >
   +0x000 _Mypair          : 
mymap                 : { size=0x5 } 
snipped
    [0x0]            : 77 'M', "Alp" [Type: 
    [0x1]            : 78 'N', "Bet" [Type: 
    [0x2]            : 79 'O', "Gam" [Type: 
    [0x3]            : 80 'P', "Del" [Type: 
    [0x4]            : 81 'Q', "Eps" [Type: 

0:000> dx ( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b930
( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b930 
snipped
    [0x1]            : 65 'A', "Alpha" [Type:
    [0x2]            : 66 'B', "Beta" [Type:
    [0x3]            : 67 'C', "Gamma" [Type:
    [0x4]            : 68 'D', "Delta" [Type:
    [0x5]            : 69 'E', "Epsilon" [Type:

0:000> dx ( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b960
( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b960 
snipped
    [0x1]            : 86 'V', "Kappa" [Type: std::pair<char const ,char const *>]
    [0x2]            : 87 'W', "Iota" [Type: std::pair<char const ,char const *>]
    [0x3]            : 88 'X', "Theta" [Type: std::pair<char const ,char const *>]
    [0x4]            : 89 'Y', "Eta" [Type: std::pair<char const ,char const *>]
    [0x5]            : 90 'Z', "Zeta" [Type: std::pair<char const ,char const *>]
ntdll!LdrpDoDebuggerBreak+0x2c:
771d05a6 cc int 3
正在处理初始命令“$$>a$$>adx(标准::映射*)0x00d6b930
(标准::映射*)0x00d6b930
剪断
[0x1]:65'A',“Alpha”[类型:
[0x2]:66“B”和“Beta”[类型:
[0x3]:67'C',“Gamma”[类型:
[0x4]:68'D',“Delta”[类型:
[0x5]:69'E',“ε”[类型:
0:000>dx(标准::映射*)0x00d6b960
(标准::映射*)0x00d6b960
剪断
[0x1]:86'V',“Kappa”[类型:标准::成对]
[0x2]:87'W',“物联网”[类型:std::pair]
[0x3]:88'X',“Theta”[类型:std::pair]
[0x4]:89'Y',“Eta”[类型:std::pair]
[0x5]:90'Z',“Zeta”[类型:std::pair]

从历史上看,windbg在实现这些奇特的显示方面落后了一两英里

也就是说你的名字空间是嵌套的吗

我假设是的,因为模块后面有一个nsmod!ns:::\>echo off ls anonall.h anonone.cpp anontwo.cpp cl /Zi /W4 /analyze /EHsc /Od /nologo anonone.cpp anontwo.cpp /link /release /nologo anonone.cpp anontwo.cpp Compiling... Generating Code... ls anonall.h anonone.obj anontwo.obj anonone.cpp anonone.pdb vc140.pdb anonone.exe anontwo.cpp anonone.nativecodeanalysis.xml anontwo.nativecodeanalysis.xml
anonone.exe
from Anonymous NS Map in anonone.cpp 15

M = Alp
N = Bet
O = Gam
P = Del
Q = Eps

from Anonymous NS Map in anonone.cpp 25

A = Alpha
B = Beta
C = Gamma
D = Delta
E = Epsilon

from Anonymous Namespace Map in anontwo.cpp

V = Kappa
W = Iota
X = Theta
Y = Eta
Z = Zeta
cdb -c ".lines;bu `anonone.cpp:33` \"x *!*mymap*\";g;q" anonone.exe

Microsoft (R) Windows Debugger Version 10.0.16299.15 X86

0:000> cdb: Reading initial command '.lines;bu `anonone.cpp:33` "x *!*mymap*";g;q'

snipp======================

0118b938          anonone!mymap = { size=0x5 }
01175198          anonone!mymap$initializer$ = 0x01101040
011742c0          anonone!`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
01101040          anonone!`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
011742e0          anonone!ns::`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
011742d0          anonone!ns::`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
01101080          anonone!ns::`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
01101060          anonone!ns::`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
0118b930          anonone!ns::`anonymous namespace'::mymap = <no type information>
0118b960          anonone!ns::`anonymous namespace'::mymap = <no type information>

quit:
ntdll!LdrpDoDebuggerBreak+0x2c:
771d05a6 cc              int     3
Processing initial command '$$>a< displayanon.txt'
0:000> $$>a< displayanon.txt
ModLoad: 6b450000 6b453000   C:\Windows\system32\api-ms-win-core-synch-l1-2-0.DLL
00d6b938          anonone!mymap = { size=0x5 }
00d55198          anonone!mymap$initializer$ = 0x00ce1040
00d542c0          anonone!`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
00ce1040          anonone!`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
00d542e0          anonone!ns::`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
00d542d0          anonone!ns::`anonymous namespace'::`dynamic atexit destructor for 'mymap'' (void)
00ce1080          anonone!ns::`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
00ce1060          anonone!ns::`anonymous namespace'::`dynamic initializer for 'mymap'' (void)
00d6b930          anonone!ns::`anonymous namespace'::mymap = <no type information>
00d6b960          anonone!ns::`anonymous namespace'::mymap = <no type information>


this is the type which you can get by using x {mod}!{std::map {wildcard}}

class std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > >
   +0x000 _Mypair          : 
mymap                 : { size=0x5 } 
snipped
    [0x0]            : 77 'M', "Alp" [Type: 
    [0x1]            : 78 'N', "Bet" [Type: 
    [0x2]            : 79 'O', "Gam" [Type: 
    [0x3]            : 80 'P', "Del" [Type: 
    [0x4]            : 81 'Q', "Eps" [Type: 

0:000> dx ( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b930
( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b930 
snipped
    [0x1]            : 65 'A', "Alpha" [Type:
    [0x2]            : 66 'B', "Beta" [Type:
    [0x3]            : 67 'C', "Gamma" [Type:
    [0x4]            : 68 'D', "Delta" [Type:
    [0x5]            : 69 'E', "Epsilon" [Type:

0:000> dx ( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b960
( std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *) 0x00d6b960 
snipped
    [0x1]            : 86 'V', "Kappa" [Type: std::pair<char const ,char const *>]
    [0x2]            : 87 'W', "Iota" [Type: std::pair<char const ,char const *>]
    [0x3]            : 88 'X', "Theta" [Type: std::pair<char const ,char const *>]
    [0x4]            : 89 'Y', "Eta" [Type: std::pair<char const ,char const *>]
    [0x5]            : 90 'Z', "Zeta" [Type: std::pair<char const ,char const *>]