Как использовать команды Windbg для просмотра записей CMap - PullRequest
0 голосов
/ 13 июня 2018

При исследовании дампа я наткнулся на объект CMap.это довольно легко отладить в Visual Studio следующим образом:

pThread->p<Class>->m_mapParameters.m_pHashTable,2741

, где 2741 - это m_nHashTableSize объекта CMap m_mapParameters.

Теперь я попытался сделать то же самое в Windbg, но это не работает.Единственное, что я могу сделать, это:

dt pThread

И затем я начинаю нажимать со следующими результатами (только автоматически сгенерированные команды):

dx -r1 ((<application>!<Class> *)0x7f8e820)
dx -r1 (*((<application>!<Class> *)0x7f8e820)),nd
dx -r1 -n (*((<application>!<Class> *)0x7f8e820)),nd

Но затем я получаюзастрял: нет способа (который я нашел) использовать количество элементов, чтобы получить полный список записей CMap.

Кто-нибудь знает, есть ли способ получить полный список записей CMap вСессия Windbg (или просмотр Windbg)?

Заранее спасибо
Доминик

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Упс, похоже, это стандартная функция команды Windbg dt:

Option           Description
======           ===========
-a[quantity]     Show each array element on a new line, with its index.
                 A total of quantity elements will be displayed.
                 There must be no space between the a and the quantity.
                 If -a is not followed by a digit, all items in the array are shown.
                 The -a[quantity] switch should appear immediately before each type name or
                 field name that you want displayed in this manner.

Однако, хотя в этом объяснении упоминается, что количество элементов не требуется, я видел случаи, когдане указание количества приводит к отображению слишком малого количества элементов.

Следовательно:

dt -a2741 pThread->p<Class>->m_mapParameters.m_pHashTable
0 голосов
/ 14 июня 2018

почему вы смотрите на pThread, когда говорите, что m_mapParameters является объектом CMap?

вы можете использовать dx m_mapParameters

ниже приведен небольшой пример кода, который реализует CMap в минимальном минимальном размере MFCприложение, скомпилированное в командной строке сообщества разработчиков vs2017 и просматривающее CMap в windbg

#define WINVER 0x501  // compiler warning for _WINNT_WINVER so adding winxp
#define _CRT_SECURE_NO_WARNINGS  // using sprintf which is deprecated
#include <afxwin.h>  
class CMainFrame : public CFrameWnd {
public: CMainFrame();
protected:
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
    Create(NULL, "MFC Test", WS_OVERLAPPEDWINDOW, CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public: BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_KEYDOWN()
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance() {
    m_pMainWnd = new CMainFrame; 
    m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();
    return TRUE;
}
CMessagesApp theApp;
CMap<UINT, UINT, CStringA, CStringA> myMap;  // global CMap Declaration
void CMainFrame::OnKeyDown(UINT nChar, UINT, UINT) {
    char buff[0x100] = { 0 }; char buffy[0x100] = { 0 };
    sprintf(buff, "you pressed %c \n", nChar);
    myMap[nChar] = CStringA(buff);  
    sprintf(buffy, "total number of keys is %d\n", myMap.GetSize());
    MessageBox(buffy);
}

, компилирующее, выполняющее нажатие нескольких клавиш клавиатуры и присоединяющее его к windbg

:\>cl /Zi /W4  /Ox /nologo /EHsc mfctest.cpp /link /nologo /subsystem:windows
mfctest.cpp

:\>mfctest.exe

:\>windbg -pn mfctest.exe

:\>

результат

0:001> dx mfctest!myMap
mfctest!myMap                 [Type: CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > >]
    [=0x5c79bc] classCObject     : {"CObject"} [Type: CRuntimeClass]
    [+0x004] m_pHashTable     : 0x8d32b8 [Type: CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > >::CAssoc * *]
    [+0x008] m_nHashTableSize : 0x11 [Type: unsigned int]
    [+0x00c] m_nCount         : 9 [Type: int]
    [+0x010] m_pFreeList      : 0x8dd958 [Type: CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > >::CAssoc *]
    [+0x014] m_pBlocks        : 0x8dd8c0 [Type: CPlex *]
    [+0x018] m_nBlockSize     : 10 [Type: int]
0:001> dx mfctest!myMap.m_pHashTable[0]->value.m_pszData
mfctest!myMap.m_pHashTable[0]->value.m_pszData                 : 0x8cf808 : "you pressed U ." [Type: char *]

0:001> dx mfctest!myMap.m_nCount
mfctest!myMap.m_nCount : 9 [Type: int]

enter image description here

РЕДАКТИРОВАТЬ вот как вы выводите CMap-> pHashTable.values ​​

эта карта имеет 26 ключевых значенийпары (a, b..z)
размер хеш-таблицы по умолчанию 0x11 (рекомендуемое простое число)

0:001> dt myMap
mfctest!myMap
   +0x000 __VFN_table : 0x0161b96c 
   =0161bba8 classCObject     : CRuntimeClass
   +0x004 m_pHashTable     : 0x002e0858  -> 0x002e0d30 CMap<cut>::CAssoc
   +0x008 m_nHashTableSize : 0x11
   +0x00c m_nCount         : 0n26
   +0x010 m_pFreeList      : 0x002e0d90 CMap<cut>::CAssoc
   +0x014 m_pBlocks        : 0x002e0d28 CPlex
   +0x018 m_nBlockSize     : 0n10

дамп массива pHashTables по умолчанию
, каждый из 0ORD DWORD ниже - указатель наpHashTable типа CMap :: CAssoc
каждый может иметь действительный член pNext или ноль, чтобы указать, что больше нет записей

0:001> dd @@c++(myMap.m_pHashTable) L @@c++(myMap.m_nHashTableSize)
002e0858  002e0d30 002e0600 002e05d0 002e05a0
002e0868  002e0d80 002e0d50 002e0620 002e05f0
002e0878  002e05c0 002e0590 002e0d70 002e0d40
002e0888  002e0610 002e05e0 002e05b0 002e0950
002e0898  002e0d60

подготовка к выгрузке с использованием средства оценки выражений c ++

0:001> $$ each of 0x11 dword are pointers to pHashTable and can have a valid pNext 
0:001> $$ lets c++ expressify the first array member
0:001> r? @$t0 = myMap.m_pHashTable[0]
0:001> ? @$t0
Evaluate expression: 3018032 = 002e0d30 <<<<< see the dump above
0:001> r? @$t0 = myMap.m_pHashTable[1]
0:001> ? @$t0
Evaluate expression: 3016192 = 002e0600 <<<<< see the dump above

0:001> $$ @$t0 represents the pHashTables and if you have sufficiently 
0:001> $$ big data m_nHashTableSize would be modified 

0:001> ?? myMap.m_nHashTableSize
unsigned int 0x11

0:001> $$ now that we have an expression that points to the first pHashTable 
0:001> we can iterate over the pNext and dump the keys

0:001> ? @$t0
Evaluate expression: 3016192 = 002e0600

dumpingфактические записи

0:001> $$ we are going to iterate the second HashTable entries
0:001> .printf "%ma\n" , @@c++(@$t0->value.m_pszData)
you pressed R 

0:001> $$ choose the pNext if it exists
0:001> .printf "%ma\n" , @@c++(@$t0->pNext->value.m_pszData)
you pressed A 

0:001> .printf "%ma\n" , @@c++(@$t0->pNext->pNext->value.m_pszData)
Memory access error at 'm_pszData)'
0:001> ? @@c++(@$t0->pNext->pNext)
Evaluate expression: 0 = 00000000
0:001> $$ we reached the end so choose the next pHashTable and repeat the process
0:001> r? @$t0 = myMap.m_pHashTable[0]
0:001> ? @$t0
Evaluate expression: 3018032 = 002e0d30
0:001> $$ we are going to iterate the first HashTable entries
0:001> .printf "%ma\n" , @@c++(@$t0->value.m_pszData)
you pressed U 

0:001> .printf "%ma\n" , @@c++(@$t0->pNext->value.m_pszData)
you pressed D 

0:001> .printf "%ma\n" , @@c++(@$t0->pNext->pNext->value.m_pszData)
Memory access error at 'm_pszData)'

пример кода JavaScript для выгрузки записей CMap для создания экземпляра CMap (int, int.CString, CString) с использованием класса Description из dt / v / t mfctest! MyMap

"use strict";
// usage !dumpcmap address
// typeDescription is copied from windbg dt /v /t myMap for this instantiation
// of CMap (int,int,CString,Cstring) myMap and pointerised 
function initializeScript() {
    return [new host.functionAlias(dump_CMap, "dumpcmap")];
}

function log(instr) {
    host.diagnostics.debugLog(instr + "\n")
}

function dump_CMap(input ) {
    var typeDescription = "(CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > > *)"
    var foo = host.evaluateExpression( typeDescription + input.toString() )
    for(var i =0; i< foo.m_nHashTableSize ; i ++) {
        log (foo.m_pHashTable[i].value)
        if(foo.m_pHashTable[i].pNext != 0) {
            log (foo.m_pHashTable[i].pNext.value)
        } 
    }
}

результат jsисполнение

0:001> ? myMap
Evaluate expression: 17889164 = 0110f78c
0:001> ?? myMap
class CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > >
   +0x000 __VFN_table : 0x0108b96c 
   =0108bba8 classCObject     : CRuntimeClass
   +0x004 m_pHashTable     : 0x00325660  -> 0x00331460 CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > >::CAssoc
   +0x008 m_nHashTableSize : 0x11
   +0x00c m_nCount         : 0n26
   +0x010 m_pFreeList      : 0x003314c0 CMap<unsigned int,unsigned int,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >,ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > > >::CAssoc
   +0x014 m_pBlocks        : 0x00331458 CPlex
   +0x018 m_nBlockSize     : 0n10
0:001> .scriptload c:\wdscr\dump_cmap.js
JavaScript script successfully loaded from 'c:\wdscr\dump_cmap.js'
0:001> !dumpcmap 0x0110f78c
"you pressed U"
"you pressed D"
"you pressed R"
"you pressed A"
"you pressed O"
[object Object]
"you pressed L"
[object Object]
"you pressed Z"
"you pressed I"
"you pressed W"
"you pressed F"
"you pressed T"
"you pressed C"
"you pressed Q"
[object Object]
"you pressed N"
[object Object]
"you pressed K"
[object Object]
"you pressed Y"
"you pressed H"
"you pressed V"
"you pressed E"
"you pressed S"
"you pressed B"
"you pressed P"
[object Object]
"you pressed M"
[object Object]
"you pressed J"
[object Object]
"you pressed X"
"you pressed G"
@$dumpcmap(0x0110f78c)
...