デバッガ開発で大きな壁が
abdev 10月 28th, 2005今日は一日中パソコンです。外はいい天気なのにな〜。
さてさて、ここらで気分を変えて、64コンパイラが生成したコードをデバッグするためのデバッガ造りを始めることにしたのですが、、、
初っ端から躓いております。GetThreadContext関数が正常に動作しません。この関数に渡すCONTEXT構造体は、CPUレジスタの内容を管理するデータ構造になっておるため、x86とAMD64のそれとでは内容が違います。
そこで、Microsoft Platform SDK2003から下記のような構造体を引っ張り出してきまたんです。正式にはCONTEXT構造体として定義されていますが、おいらが作業を行っているVC6ではすでに同じ名前でx86用のものが定義されています。そんな理由から、構造体名がCONTEXT64に変わっているのです。
struct CONTEXT64 { // // Register parameter home addresses. // // N.B. These fields are for convience - they could be used to extend the // context record in the future. // DWORD64 P1Home; DWORD64 P2Home; DWORD64 P3Home; DWORD64 P4Home; DWORD64 P5Home; DWORD64 P6Home; // // Control flags. // DWORD ContextFlags; DWORD MxCsr; // // Segment Registers and processor flags. // WORD SegCs; WORD SegDs; WORD SegEs; WORD SegFs; WORD SegGs; WORD SegSs; DWORD EFlags; // // Debug registers // DWORD64 Dr0; DWORD64 Dr1; DWORD64 Dr2; DWORD64 Dr3; DWORD64 Dr6; DWORD64 Dr7; // // Integer registers. // DWORD64 Rax; DWORD64 Rcx; DWORD64 Rdx; DWORD64 Rbx; DWORD64 Rsp; DWORD64 Rbp; DWORD64 Rsi; DWORD64 Rdi; DWORD64 R8; DWORD64 R9; DWORD64 R10; DWORD64 R11; DWORD64 R12; DWORD64 R13; DWORD64 R14; DWORD64 R15; // // Program counter. // DWORD64 Rip; // // Floating point state. // union { XMM_SAVE_AREA32 FltSave; struct { M128A Header[2]; M128A Legacy[8]; M128A Xmm0; M128A Xmm1; M128A Xmm2; M128A Xmm3; M128A Xmm4; M128A Xmm5; M128A Xmm6; M128A Xmm7; M128A Xmm8; M128A Xmm9; M128A Xmm10; M128A Xmm11; M128A Xmm12; M128A Xmm13; M128A Xmm14; M128A Xmm15; }; }; // // Vector registers. // M128A VectorRegister[26]; DWORD64 VectorControl; // // Special debug control registers. // DWORD64 DebugControl; DWORD64 LastBranchToRip; DWORD64 LastBranchFromRip; DWORD64 LastExceptionToRip; DWORD64 LastExceptionFromRip; };
↑ハァ〜長いです。
で、実際にスレッドごとのCPUレジスタの内容を取得するには、下記のようなコードで実現できます。
CONTEXT64 Context; Context.ContextFlags=CONTEXT_ALL64; GetThreadContext(hThread,(LPCONTEXT)&Context);
実現できるはずなのですが、いくらやってもGetThreadContextの戻り値は1が帰るのに、肝心の構造体が書き換わりません。なんででしょ〜???
かれこれ、この問題に3時間も費やしております。いい天気なのに・・・
10月 28th, 2005 at 17時12分55秒
FALSEを返さないのにうまくいかないというのは謎ですね。http://msdn.microsoft.com/library/en-us/debug/base/context_str.aspところでWOW64ではスレッドハンドルにTHREAD_QUERY_INFORMATIONが必要と書いてあります。(既にご覧でしたら失礼しました)私の想像ですが,WOW64ではCONTEXT構造体もx86用のものを受け付けるようになっていないでしょうか?たとえそうだとしたらx86用のCONTEXTとして部分的に書き換えられるでしょうとは思うのですが一応。
10月 28th, 2005 at 20時55分01秒
デバッグ対象のプログラムがWOW64で動くWin32アプリなら問題なくCONTEXTを取得できておるのですが、問題なのはデバッグ対象のプログラムがネイティブな64アプリの場合です。※デバッガはWOW64の機構を利用したWin32で動いてます。CONTEXT64の情報をGetThreadContextで取得するには、デバッガもネイティブな64アプリとして動かなくちゃダメなんですかね??ちょっと、本格的に行き詰っているんで、明日あたり、詳細情報を公開して皆さんにヘルプを頼むかもしれません…(あ〜困った
10月 29th, 2005 at 1時10分34秒
CONTEXT64は、Win64アプリに対してのものですので、Win32では既存のCONTEXTになります。既存のCONTEXTは、VC6など昔ながらのx86レジスタ情報を保有しているやつです(VCについているwinnt.hを見るとよくわかるかも…)。一日中考えてらちがあかなかったので、詳細情報を公式に提示してみます。今しばらくお待ちを…。P.S.64PC、私は実家へ帰ったときでも作業ができるようにノート型のやつが欲しいっす。アンケートを見ると、まだ持っている方は少ないみたいですな(~~
10月 29th, 2005 at 23時11分11秒
「WOW64で動くWin32アプリなら問題なくCONTEXTを取得できる」というのはあのCONTEXT64を使ってですか?何にしても私はそもそも64bit PCを持っていないので実際に試したりはできないのがつらいです。