2014-11-20 2 views
3

Я хотел бы набрать объект дочернего класса родительскому классу в WinDbg в окне команд.Windbg Type Casting

Примеры классов

class parent 
{ 
public: 
    int a; 
    int b; 
    parent(){ a = 10; b = 10; } 
    parent(int c) : a(a){} 
}; 

class child : public parent 
{ 
public: 
    int a; 
    int b; 
    child(){ a = 20; b = 20; } 
    child(int d) : b(d){} 
}; 

Я использую Windbg и я читал через файл справки. Он показывает под номерами и операторами, что я могу сделать следующее typecastings из окна командной WinDbg C++:

dynamic_cast <type>(Value) 
static_cast <type>(Value) 
reinterpret_cast <type>(Value) 
const_cast <type>(Value) 
(type) Value 

Так что я бы ввести в окне командной строки Windbg:

?? (type) Value 

Что работает в

?? (char)a 
?? static_cast<char>(a) 

где a является инт.

Что не работает в

?? (parent)chld 
?? static_cast<parent>(chld) 
?? static_cast<mod!parent>(chld) 

где CHLD является объектом класса ребенка и ребенка наследует класс родителя. Пример

объект:

child chld; 

Обнаружена ошибка ошибка

Тип конфликта в '<EOL>'

Если я делаю x mod!* я получаю гигантский список, в этом списке:

MOD!parent 
MOD!child 

Если я делаю ?? chld, тогда объект будет сбрасываться на экран просто отлично.

Почему я хотел бы это сделать? Ну вы можете сделать

?? chld.childattr++, и поэтому я хотел бы на самом деле ?? ((parent)chld).parentattr++

WinDbg помощь говорит:

символы в C++ Выражения

В выражении C++ каждый символ интерпретируется по его типу. В зависимости от того, на что указывает этот символ, его можно интерпретировать как целое число, структуру данных, указатель функции, или любой другой тип данных. Если вы используете символ, который не соответствует типу данных C++ (например, имя немодифицированного модуля) в выражении C++, возникает синтаксическая ошибка.

Поэтому я не вижу причин, по которым я не должен был бы набирать объект для родительского типа данных.

Я много раз искал, и ничего не пришло в голову, если бы кто-то мог указать мне в правильном направлении, чтобы я мог прочитать, почему это должно или не должно работать, или, может быть, что мне нужно сделать, чтобы быть успешный или даже почему это не то, что я должен ожидать от WinDbg.

Отредактировано: Добавить пример кода.

ответ

5

код, фрагмент кода или что-нибудь, что является воспроизводимым в какой-то степени в других машинах могут обеспечить более надежные и ясные ответы, а не сухой теоретический вопрос

я истолковать ваш вопрос быть типа может ре заголовок архивируются _eprocess структура

если так что вы можете сделать некоторые вещи, как этот

lkd> ?? (char *)@$proc->ImageFileName 
char * 0x866be194 
"windbg.exe" 
lkd> lm m windbg 
start end  module name 
01000000 01097000 windbg  (pdb symbols)   
lkd> db windbg l10 
01000000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ.............. 
lkd> da windbg+4e 
0100004e "This program cannot be run in DO" 
0100006e "S mode....$" 
lkd> ?? (char *)((nt!_EPROCESS *) @@masm(windbg - 174+4e))->ImageFileName 
char * 0x0100004e 
"This program cannot be run in DOS mode....$" 

хотя до сих пор при потере этого правка в ответ на отредактированной вопрос

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

:\>type parchiltst.cpp 
#include <stdio.h> 
class parent 
{ 
public: 
    int a; 
    int b; 
    parent(){ a = 35; b = 28; } 
    parent(int c) : a(c){} 
}; 
class child : public parent 
{ 
public: 
    int a; 
    int b; 
    child(){ a = 20; b = 20; } 
    child(int d) : b(d){} 
}; 
int main (void) { 
    parent par,papa,mama,gramp; 
    child chill,bigbro,lilsis,crybab; 
    par.a=70;par.b=65;chill.a=4;chill.b=8; 
    gramp=parent(par); papa=parent(); mama=parent(1234); 
    bigbro=child(chill);lilsis=child();crybab=child(5678); 
    printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", 
     chill.a,chill.b,gramp.a,gramp.b,papa.a,papa.b,mama.a,mama.b, 
     bigbro.a,bigbro.b,lilsis.a,lilsis.b,crybab.a,crybab.b); 
    return 0; 
} 

скомпилирован, связаны между собой и выполнены, чтобы показать выход

:\>cl /Zi /nologo /W4 /analyze parchiltst.cpp /link /RELEASE 
parchiltst.cpp 

:\>parchiltst.exe 
4 8 70 65 35 28 1234 0 4 8 20 20 196608 5678 ` 

загрузка под windbg и stepping upto printf, чтобы все местные жители были правильно инициализированы

:\>cdb parchiltst.exe 

0:000> g main 
parchiltst!main: 
00401000 55    push ebp 
0:000> dv -V -t -i 
prv local 0013ff18 @ebp-0x60 class child lilsis = class child 
prv local 0013ff28 @ebp-0x50 class parent par = class parent 
prv local 0013ff30 @ebp-0x48 class parent gramp = class parent 
prv local 0013ff38 @ebp-0x40 class parent papa = class parent 
prv local 0013ff40 @ebp-0x38 class parent mama = class parent 
prv local 0013ff48 @ebp-0x30 class child chill = class child 
prv local 0013ff58 @ebp-0x20 class child bigbro = class child 
prv local 0013ff68 @ebp-0x10 class child crybab = class child 
0:000> .lines 
Line number information will be loaded 
0:000> l+* 
0:000> p 
> 19:  parent par,papa,mama,gramp; 
0:000> 
> 20:  child chill,bigbro,lilsis,crybab; 
0:000> 
> 21:  par.a=70;par.b=65;chill.a=4;chill.b=8; 
0:000> 
> 22:  gramp=parent(par); papa=parent(); mama=parent(1234); 
0:000> 
> 23:  bigbro=child(chill);lilsis=child();crybab=child(5678); 
0:000> 
> 26:   bigbro.a,bigbro.b,lilsis.a,lilsis.b,crybab.a,crybab.b); 

оценки всех местных жителей с C++ ехр оценщиком

0:000> !for_each_local "?? @#Local" 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n4 
    +0x00c b    : 0n8 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n4 
    +0x00c b    : 0n8 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n2090270496 
    +0x00c b    : 0n5678 
class parent 
    +0x000 a    : 0n70 
    +0x004 b    : 0n65 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n20 
    +0x00c b    : 0n20 
class parent 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
class parent 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
class parent 
    +0x000 a    : 0n70 
    +0x004 b    : 0n65 

проверка индивидуально

0:000> ?? ((child *) @@masm(mama))->a 
int 0n35 
0:000> ?? ((parent *) @@masm(mama))->a 
int 0n1234 
0:000> ?? ((parent *) @@masm(papa))->a 
int 0n35 
0:000> ?? ((child *) @@masm(papa))->a 
int 0n1234 
0:000> ?? ((child *) @@masm(lilsis))->a 
int 0n20 
0:000> ?? ((parent *) @@masm(lilsis))->a 
int 0n35 
0:000> ?? ((parent *) @@masm(lilsis)) 
class parent * 0x0013ff18 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
0:000> ?? ((child *) @@masm(lilsis)) 
class child * 0x0013ff18 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n20 
    +0x00c b    : 0n20 
0:000> ?? ((child *) @@masm(mama)) 
class child * 0x0013ff40 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
    +0x008 a    : 0n35 
    +0x00c b    : 0n28 
0:000> ?? ((parent *) @@masm(mama)) 
class parent * 0x0013ff40 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
0:000> 

след вопросов и ответов, которые могут привести к решениям

, что мы хотим показать?

a pointer to a class 

что тип класса

somefoo 

так, чтобы отобразить указатель на somefoo в C++ выражения оценщиком

?? (somefoo *) should be used 

указатель нужен адрес или выражение, которое вычисляется по адресу

lilsis, папа, somefoo и т.д. являются выражения, которые могут быть истолкованы как в MASM и C++ оценщики

так, чтобы избежать неоднозначности we need to explicitly state that lilsis etc needs to be evaluated as masm expression not as c++ expression because ?? tries to interpret lilsis , somefoo as c++ expression
поэтому полное выражение будет ?? (somefoo *) @@(someotherfoo)

уведомление @@ only является достаточно для указания выражения masm, но для того, чтобы избежать двусмысленности, является хорошей привычкой указывать оценки экспрессии explicitly like @@masm(, @@c++( и т. д.

см. Ниже сингла? по указателю класса возвращает адрес и a? возвращать тип

0:000> ? mama 
Evaluate expression: 1310528 = 0013ff40 
0:000> ?? mama 
class parent 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
0:000> ?? lilsis 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n20 
    +0x00c b    : 0n20 
0:000> ? lilsis 
Evaluate expression: 1310488 = 0013ff18 
0:000> ?? @@(mama) 
unsigned int64 0x13ff40 
0:000> ?? @@masm(mama) 
unsigned int64 0x13ff40 
0:000> ?? @@c++(mama) 
class parent 
    +0x000 a    : 0n1234 
    +0x004 b    : 0n0 
0:000> ?? @@c++(crybab) 
class child 
    +0x000 a    : 0n35 
    +0x004 b    : 0n28 
    +0x008 a    : 0n2090270496 
    +0x00c b    : 0n5678 
0:000> 

это относится не только к классу, но и types displayed with dt

нт! _eprocess манипулируют ниже для различных scenerios в качестве примера

LKD> ?? (! (Нуклеотиды _EPROCESS) @ $ прок) -> ImageFileName

Type conflict error at ')->ImageFileName' 

LKD> ?? (! (Нуклеотиды _EPROCESS *) @ $ прок) -> ImageFileName

unsigned char [16] 0x86305f14 
0x6b 'k' 

LKD> ?? (Символ *) (! (Нуклеотиды _EPROCESS *) @ $ прок) -> ImageFileName

char * 0x86305f14 
"kd.exe" 

LKD> ?? (Символ *) ((нт _EPROCESS *) нт!) -> ImageFileName

Couldn't resolve error at 'nt)->ImageFileName' 

LKD> ?? (Символ *) ((нт _EPROCESS *) @@ (нт)!) -> ImageFileName

char * 0x804d7174 
"" 

?? #FIELD_OFFSET (нт! _EPROCESS, ImageFileName)

long 0n372 

LKD>?0n372

Evaluate expression: 372 = 00000174 

LKD>? @@ C++ (# FIELD_OFFSET (нт! _EPROCESS, ImageFileName)) + нт

Evaluate expression: -2142408332 = 804d7174 

LKD> ?? @@ C++ (# FIELD_OFFSET (нт! _EPROCESS, ImageFileName)) + нт

Couldn't resolve error at 'nt' 

LKD> ?? @@ C++ (# FIELD_OFFSET (нуклеотиды _EPROCESS, ImageFileName!)) + @@ (нт)

unsigned int64 0xffffffff`804d7174 
lkd> 
+0

Я так понял вопрос: он работает со встроенными типами данных, но не C++ пользовательских классов. –

+0

Да, Томас У. верно в том, что я прошу. Я отредактирую вопрос и добавлю пример. Спасибо за ответ Блаб. –

+0

добавил немного воспроизводимого редактирования к моему оригинальному ответу, посмотри, посмотрим, поможет ли он – blabb