我已经使用Windbg几个月了,最后决定写一个脚本。我的目的是绕过STL地图的节点并显示键/值对。我已经到了输出我发现的东西的地步,但我的简单问题是我是否可以解析输出以使其更清晰,因为当我转储_Myval.first._Bx
时,它被许多无关的信息所包围_Myval.second._Bx
通过??
- 我喜欢就是让我感兴趣的东西,如果可能的话。
例如,当我这样做时,不要看到这个:
.printf "\nTREE MAP NODE: %p\n", @$t0
.printf " KEY = "
?? @$t0->_Myval.first._Bx
TREE MAP NODE: 00000010bc1f2cb0
KEY = union std::_String_val<char,std::allocator<char> >::_Bxty
+0x000 _Buf : [16] "Connections"
+0x000 _Ptr : 0x00004c5353657355 "--- memory read error at address 0x00004c5353657355 ---"
+0x000 _Alias : [16] "Connections"
我想看到这个:
TREE MAP NODE: 00000010bc1f2cb0
KEY = "Connections"
所以我最终可能会这样显示:
TREE MAP NODE: 00000010bc1f2cb0
KEY = "Connections"
VALUE = "10"
TREE MAP NODE: 00000010bc1f2cc0
KEY = "StartupTask"
VALUE = "TestTask"
TREE MAP NODE: 00000010bc1f2cd0
KEY = "Location"
VALUE = "UK"
我知道我可以使用??
来查看某个节点_Myval.first
,其中显示了其中包含的内容的大小,例如0xb
我甚至可以通过_Myval.first._Mysize
返回unsigned int64 0xb
来解决这个问题,但是我可以对内容做同样的事情吗?
这可能是我缺乏经验,但如果我尝试在_Myval.first._Bx._Buf
中显示什么,那么我只是得到一个地址并返回第一个字符,例如'C'
...所以,我的问题就是这个 - 因为我知道 我想要的东西,我知道 long < / em>它是(如果我需要知道这一点) - 那么我怎样才能显示那个......而不是当前带有_Bx
,_Buf
和_Ptr
的整个_Alias
Application.CutCopyRange
?
答案 0 :(得分:1)
如下所示是在windbg中播放STL模板显示的几个例子
尝试新的dx表达式求值程序,它向下钻取到最后一个成员并且相当打印
如果您使用最新的windbg版本而不是windbgs本机脚本,也可以使用javascript
假设一个私有pdb代码正在调试
如果在函数上初始化地图后完成 dv 如果迭代器可用,可以直接使用
0:000> ?? iter._Ptr->_Myval.second
char * 0x000341a0
"Alpha"
如果想要以粗体显示printf
.printf /D "contents of iter_.second is <b>%ma</b>\n" , @@c++(iter._Ptr->_Myval.second)
contents of iter_.second is Alpha
如果想要枚举地图中的每一对,则必须枚举父左右分支
0:000> ?? mymap._Mypair._Myval2._Myval2._Myhead->_Parent->_Myval
struct std::pair<char const ,char const *>
+0x000 first : -120 '' (eax)
+0x004 second : 0x000341a8 "Beta"
0:000> ?? mymap._Mypair._Myval2._Myval2._Myhead->_Left->_Myval
struct std::pair<char const ,char const *>
+0x000 first : -120 '' (eax)
+0x004 second : 0x000341a0 "Alpha"
0:000> ?? mymap._Mypair._Myval2._Myval2._Myhead->_Right->_Myval
struct std::pair<char const ,char const *>
+0x000 first : -120 '' (eax)
+0x004 second : 0x000341c0 "Epsilon"
如果需要打印右分支(地图中的最后一个成员)
.printf "the last memeber in map is %ma\n" , @@c++(mymap._Mypair._Myval2._Myval2._Myhead->_Right->_Myval.second)
the last memeber in map is Epsilon
使用最新的dx表达式评估器来打印几乎所有内容
0:000> dx mymap
mymap : { size=0x5 } [Type: std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > >]
[<Raw View>] [Type: std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > >]
[comparator] : less [Type: std::_Compressed_pair<std::less<char>,std::_Compressed_pair<std::allocator<std::_Tree_node<std::pair<char const ,char const *>,void *> >,std::_Tree_val<std::_Tree_simple_types<std::pair<char const ,char const *> > >,1>,1>]
[allocator] : allocator [Type: std::_Compressed_pair<std::allocator<std::_Tree_node<std::pair<char const ,char const *>,void *> >,std::_Tree_val<std::_Tree_simple_types<std::pair<char const ,char const *> > >,1>]
[0x0] : 65 'A', "Alpha" [Type: std::pair<char const ,char const *>]
[0x1] : 66 'B', "Beta" [Type: std::pair<char const ,char const *>]
[0x2] : 67 'C', "Gamma" [Type: std::pair<char const ,char const *>]
[0x3] : 68 'D', "Delta" [Type: std::pair<char const ,char const *>]
[0x4] : 69 'E', "Epsilon" [Type: std::pair<char const ,char const *>]
使用dx表达式求值程序可以将任何地址转换为地图,如此
dx @$myvar = ((stdmap!std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > * ) 0x17fb90)
演员表演后 一个人可以像这样使用它
0:000> .for (r $t0 = 0 ; @$t0 < 5 ; r $t0 = @$t0+1) { dx @$myvar[0][@$t0].second }
@$myvar[0][@$t0].second : 0x341a0 : "Alpha" [Type: char *]
@$myvar[0][@$t0].second : 0x341a8 : "Beta" [Type: char *]
@$myvar[0][@$t0].second : 0x341b0 : "Gamma" [Type: char *]
@$myvar[0][@$t0].second : 0x341b8 : "Delta" [Type: char *]
@$myvar[0][@$t0].second : 0x341c0 : "Epsilon" [Type: char *]
_Bx等属于std :: string而不是映射
打印std :: string
0:000> .printf "%ma\n" , @@c++(test._Mypair._Myval2._Bx._Ptr)
Hello I am Me Are You Thou
_Bx是工会使用适当的成员
0:000> ?? test._Mypair._Myval2._Bx._Buf
char [16] 0x0013f888
96 '`'
0:000> ?? test._Mypair._Myval2._Bx._Ptr
char * 0x001a9860
".Hello I am Me Are You Thou."
0:000> ?? test._Mypair._Myval2._Bx._Alias
char [16] 0x0013f888
96 '
或将其转换为适合打印的类型
0:000> ?? (char *)*(unsigned long *)test._Mypair._Myval2._Bx._Buf
char * 0x001a9860
".Hello I am Me Are You Thou."
或者这里是适用于_Buf的printf变体,其中包含_Ptr
0:000> .printf "%ma\n" , @@c++( *(char **)(test._Mypair._Myval2._Bx._Buf) )
Hello I am Me Are You Thou
如果有人想跟进 用于显示这些结果的代码如下
using namespace std;
#define ALLOCSIZ 5
const char *Greek_Alphabets[ALLOCSIZ] = { "Alpha","Beta","Gamma","Delta","Epsilon" };
__declspec(noinline) void play_with_map() {
cout << "playing with maps\n\n";
map<char, const char*> mymap;
for (int i = 0; i < ALLOCSIZ; i++) {
mymap.insert(pair<char, const char*>('A' + i, Greek_Alphabets[i]));
}
map<char, const char*>::iterator iter = mymap.begin();
for (iter; iter != mymap.end(); iter++)
cout << iter->first << " = " << iter->second << "\n";
}
__declspec(noinline) void play_with_vector(){
cout << "playing with vectors\n\n";
vector< pair< char, const char* > > myvec;
for (int i = 0; i < ALLOCSIZ; i++) {
myvec.push_back(make_pair('A' + i, Greek_Alphabets[i]));
}
for (int i = 0; i < ALLOCSIZ; i++) {
cout << myvec[i].first << " = "<< myvec[i].second <<"\n";
}
}
int main() {
play_with_map();
play_with_vector();
return 0;
}
std :: string函数如下
__declspec(noinline) void play_with_std_string() {
string test("\nHello I am Me Are You Thou\n");
cout << test.c_str();
}
转储std :: map map&lt; char,const char *&gt;的示例Javascript MyMap中强>
"use strict";
// make an alias so that it can be used like regular bang command !dumpmap address
function initializeScript() {
return [new host.functionAlias(dump_std_map, "dumpmap")];
}
// a helper to log strings
function log(instr) {
host.diagnostics.debugLog(instr + "\n")
}
//use dt /v /t std::map* to get a type description string and pass it
// or use the default (applicable for this example only
// std::map< int , int > will not pan for std::map <bar , foo >
function dump_std_map(input , typedesc) {
var typeDescription;
if(typedesc) {
typeDescription = typedesc
}else {
typeDescription = "(std::map<char,char const *,std::less<char>,std::allocator<std::pair<char const ,char const *> > > *)"
}
var foo = host.evaluateExpression( typeDescription + input.toString() )
var mapsize = foo._Mypair._Myval2._Myval2._Mysize
for (var i=0; i<mapsize;i++)
{
log (foo.dereference().Skip(i).First().toString())
}
}
并像
一样使用它0:000> ? mymap
Evaluate expression: 2357904 = 0023fa90
0:000> !dumpmap 0x23fa90
65 'A', "Alpha"
66 'B', "Beta"
67 'C', "Gamma"
68 'D', "Delta"
69 'E', "Epsilon"
@$dumpmap(0x23fa90)