フラット サンクをデバッグする方法

文書翻訳 文書翻訳
文書番号: 133722 - 対象製品
すべて展開する | すべて折りたたむ

目次

概要

サンク コンパイラによって生成されたフラット サンクをデバッグするためは困難なサンクのメカニズムは複雑でサンク トレースできるデバッグ ツールは使用が困難です。 この資料では、フラット サンク、特定デバッグの手法のいくつか、および多くの一般的な thunking 問題の解決方法を説明するトラブルシューティング ガイドのデバッグの全体的な戦略を示しします。

詳細

DLL をターゲットは作業項目の制限

サンクのデバッグを開始する取得、前に保持 DLL、サンクの内部はどのようなターゲットにいくつかの制限があることに注意してください。 これは Win32 ベースの DLL を呼び出す、Win16 ベースのアプリケーションが Win32 ベースのプロセスでないためなので、同様に、Win16 ベースの DLL を呼び出す、Win32 ベースのアプリケーションはいない Win16 ベースのプロセスです。 一般的な特定の制限のとおりです。

  • サンクの内部スレッド Win32 ベースの DLL に Win16 ベースのアプリケーションから作成できません。
  • サンクによって呼び出される Win32 ベースの DLL 内のコードは、呼び出し元の Win16 ベースの処理が Win32 ベースのアプリケーションよりもはるかに小さいスタックほとんどスタック領域に必要。
  • 割り込みサービス ルーチン (ISR) が含まれている Win16 ベースの DLL する必要があります割り込みを処理中に Win32 ベースの DLL にサンクされません。
  • Win32 ベースのアプリケーション サンクまたはスタックの切り替えが Win16 ベースの DLL の呼び出しのパラメーターとして、スタック上にあるデータへのポインターを渡しませんする必要があります。

フラット サンクのデバッグができない危険である理由

フラット サンク メカニズムが、Windows カーネルの複雑な一部のために部分的、フラット サンクのデバッグは困難です。 16 ビット コードでと逆に 32 ビット コンパイル済みコードでの関数呼び出しを変換する必要があります、という事実から、複雑さの語幹は互換性のある </a0> を呼び出します。 32 ビット コードは異なるデータ型を使用して CPU 16 ビット コードからのセットを登録するため、フラット サンク機構は、必要があります関数パラメーターの変換、スタック、切り替えて戻り値を変換します。 これは、速度、用に最適化されたまだによりプリエンプティブ以外の Win16 コードを呼び出すプリエンプティブの Win32 コードの必要があります。 サンク コンパイラ </a0> は、手動で作成するよりもはるかに簡単作成フラット サンクをなりますが、安全な方法ではありません。

フラット サンクをデバッグするためは困難ですいないのみメカニズム自体が複雑でも、必要なデバッグ ツールは困難であるためにマスターします。 アプリケーション レベル デバッガー WinDBG、Microsoft Visual C++ デバッガーできませんトレース サンクによって両方の 32 ビットと 16 ビット コードから成る、システムまたは、Win16Mutex を解放する要求はありますのでなどです。 トレース、サンクによってするには WDEB386.EXE など、システムレベル デバッガーを使用します。 WDEB386.EXE を使用する主な短所は、Intel x86 マイクロプロセッサのしくみを理解、Intel x86 アセンブリ言語を把握する必要が多くのデバッガーのコマンドを覚えとします。

使用する最適な戦略は、

サンクのデバッグに最適な方法を分割およびためにを征服するは比較的簡単であり、システム レベルのデバッガーでのアセンブリ言語コードによってトレースする前に、問題のほとんどを排除します。 それらをまとめてテストする前に単独でこれらの各をテストすることが、フラット サンクはの Win32 ベースの DLL と、Win16 ベースの DLL で構成されます。 Win16 ベース、Win16 ベースの DLL をテストするアプリケーションを作成し、Win32 ベースの DLL をテストする Win32 ベース アプリケーションを作成します。 これを各辺が適切に動作する確認デバッグ ツールのさまざまなを使用できます。

サンク コンパイラでコンパイルする前に、暫定的なチェックリスト

各辺が正常に動作する、確認した後のサンク自体をテストする 2 つにします。 サンク コンパイラでサンクをコンパイルする前に、次の項目の暫定的なチェックを行います。
  1. 各関数に、正しい数とパラメーターの型にすること、サンク スクリプトを確認します。 また、パラメーターの型が、サンク コンパイラによってサポートされるを確認します。 、ない場合、サポートされている型を持つデータを渡すパラメーターを何らかの理由で変更する必要があります。
  2. 任意の構造体をパラメーターとして渡すと場合、確認、Win32 ベースの DLL、Win16 ベースの DLL、サンク スクリプト梱包同じ構造を使用してください。 および、サンク コンパイラのコマンドライン、C および C++ コンパイラのコマンドラインでは、構造体のパッキングを設定します。 サンク コンパイラの梱包のスイッチが、32 ビット側の大文字と小文字、16 ビット側のことを確認します。
  3. 確認するサンクいる関数は正しくエクスポート 32 ビットの場合に、16 ビット版の場合、その場合の規則や _stdcall を呼び出す PASCAL を使用します。 サンク コンパイラは、呼び出し規約 _ _fastcall とに従って _cdecl サポートしません。
  4. Win32 ベースの DLL 呼び出す ThunkConnect32()、DllMain() 関数が呼び出されるたびを確認します。 Win16 ベースの DLL が、エクスポート DllEntryPoint() 関数を LibMain()、ThunkConnect16() の呼び出しを ThunkConnect16() が成功したかどうかは TRUE 返すとは異なるかどうかを確認して同様に、します。

    : を実際に呼び出す XXX_ThunkConnect16() と XXX_ThunkConnect32() XXX は、記号の位置、サンク コンパイラの-t スイッチで定義します。 これらのシンボルを使用してテーブル ThunkConnect16() と ThunkConnect32 の呼び出しを生成するサンク コンパイラによって生成されたコードを示します。
  5. サンク コンパイラのコマンドラインの-t スイッチで指定された値が、Win32 および Win16 サンクの DLL の両方に対して同じことを確認します。 値は、(手順 4 でメモを参照)、Win16 ベースおよび Win32 ベースの DLL での ThunkConnect 呼び出しのプレフィックスにも対応する必要があります。
  6. Win16 ベースの DLL がモジュール定義 (.DEF) ファイルで RESIDENTNAME キーワードを使ってエクスポート DLLEntryPoint ことを確認します。 RESIDENTNAME キーワードを使用せず、ThunkConnect32 と ThunkConnect16 の呼び出しは失敗し、DLL は読み込まれません。
  7. 16 ビット DLL がモジュール定義 (.DEF) ファイルで RESIDENTNAME キーワードを使ってエクスポート XXX_ThunkData16 ことを確認します。
  8. リソース コンパイラは 4. 0 として、DLL をマークすることを Win16 ベースの DLL のメイクファイルで確認します。 4. 0 より小さいマークされている場合に、ロードされませんが、サンクが失敗します。
  9. 32 ビットから 16 ビットのサンク関数のポインターを返した場合は、基本型が両側、16 ビットおよび 32 ビット サンクの同じサイズを確認します。 基本型のサイズが異なる場合から、サンク コンパイラ発行、エラー メッセージという、「できないポインターに戻る non-identical の種類」 この問題を回避するには 1 つの方法は、異なるが互換性のある、データ型が、ポインターに戻りますです。 たとえば、サンク ポインターへ返せません int int が 16 ビット側では、32 ビット側での 4 バイトは、2 バイト。 サンクの戻り値の種類をポインターからサンク スクリプトで、Win16 ベースおよび Win32 ベースの DLL のソース コードを長整数へのポインターを int に変更します。

    ポインターを表す 16 ビットから 32 ビット サンクを記述する場合、サンク コンパイラ発行「ポインター型が返されません」を示す、エラー メッセージは、 サンク コンパイラは、ポインターが正しい Win32 ベースのプロセス アドレス空間内のデータを指していないサンクは、32 ビット関数から返されると、ために、ポインター型を取得する 16 ビットから 32 ビット サンク許可しません。 これは Win32 ベースのすべてのプロセスのアドレス スペースは、同じ範囲のアドレスをして、preemptively のコンテキスト切り替えがためです。
  10. シンボルはすべてのソース コード、モジュール定義ファイル、および、サンク スクリプト全体で一貫したスペルがある関数名をリンカー「未解決外部」エラーを報告する、出現するすべてのプロトタイプが一貫性のあることを確認します。 Win32 側で、_ _stdcall 型で、サンク関数を宣言する必要がありますので、Win16 側では、関数、PASCAL 型で宣言する必要があります。 C++ プロジェクトで必ず宣言し、_ _stdcall または PASCAL 型に加えて extern"C"リンケージ指定子を持つサンク関数の両側を定義します。

-、サンク コンパイラでコンパイル後のトラブルシューティング ガイド

preliminaries、チェックインした後、サンクの DLL をビルドし、それらを実行してください。 場合は、実行することを確認している、ロックが実線にさらにテストに進みます。 を実行しない場合使用、次のトラブルシューティング ガイドしてを判断、問題の原因を修正します。

次の Win32 側に ThunkConnect32()、Win16 ThunkConnect16() 失敗します。

  1. システム DLL のデバッグ バージョンを実行します。 KERNEL32.DLL と KRNL386.EXE のデバッグ バージョンは、サンクが初期化されなかった理由を確認する多くの診断メッセージを含めます。 デバッグ バージョンのシステム DLL を実行するには、[Win32 SDK ツールの [スタート] メニュー"デバッグ DLL への切り替え"アイコンを使用します。 "非デバッグ DLL に切り替える] を使用して、製品版に戻るにします。
  2. 確認、Win16 ベースの DLL が ThunkConnect16() を呼び出して、Win32 ベースの DLL が対応する ThunkConnect32() を呼び出してします。 以下のいずれかが見つからない場合もう一方は失敗し、サンク DLL は読み込みに失敗します。
  3. Win32 DLL の DllMain() でブレークポイントを置き、Win16 DLL の DllEntryPoint() と LibMain() で DLL を参照する関数は、読み込んでいないします。
ThunkConnect16() と ThunkConnect32() の呼び出しが正しく、動作、サンクがまだない場合は、今度、サンクを簡略化には。 この 2 つの方法で攻撃する実際にできます。 まず、1 つずつ、サンクからパラメーターを削除して再コンパイルしてください。 または、2 つ目が動作する単純なサンクを作成し、まで次の手順を実行して失敗した場合、ビルドします。
  1. 単純なサンクを作成し、サンク メカニズムを正しく設定が確認するだけで実行します。 単純なサンクに適してはない戻り値とパラメーターのない関数です。 でも単純なサンクが機能しない場合が正しくセットアップ処理を確認して、上のチェックリストの暫定的な項目をすべて実行します。 [手順 2 に進みます。
  2. ターゲット DLL を確認する確認し、依存 DLL を検出およびロードできます。 場合 1 が存在しないか、または、ローダーを検索できない場合、サンク不正解です。
  3. ターゲットの DLL がない、サンクのコンテキストでできないものを実行して確認します。
動作する単純なサンクが、実際のサンクそれでも機能しない、1 回以下の手順に従います。
  1. パラメーターを 1 単純なサンクをパラメーターが、障害を原因かどうかを調べるには、一度に追加します。 いずれかある場合、パラメーターが、関数が宣言されているし、同じ数と両方の DLL では、サンク コンパイラでパラメーターの型で定義したこと、正しい型であり関数が PASCAL または _stdcall として宣言されていることを確認します。
  2. ターゲットの DLL が Win16 ベースの DLL で、そのグローバルまたは静的データにアクセスできない場合確認、関数は正しくエクスポートしたしてください。 Visual C++ で/GD スイッチを使用する場合を宣言し、__export キーワードを使って、関数は、Win16 ベースの DLL のソース コードで定義する必要があります。 だけで、DLL のモジュール定義 (.DEF) ファイルで関数の名前を一覧に十分なためには、プロローグを生成しませんが関数をエクスポートするエピローグ コードが必要なため、コンパイラは、.DEF ファイルは処理されません。
  3. Win16 ベースの DLL 原因、ターゲット一般保護 (GP) 違反で LocalAlloc() を呼び出すことを確認する場合、関数が 2 の手順に従ってエクスポートされます。
  4. 場合、GP フォールト KERNEL32 内にだけ取得する対象となる後 Win16 ベース関数を対象の関数が宣言および PASCAL として定義されていることを確認します。 C 呼び出し規約を使用できません。 多く、アセンブリ言語では、C または C++ のコードでまれをターゲット関数、DS、SS、BP、SI、または DI レジスタを変更しなかったことを確認します。
  5. Win32 ベースのターゲット関数リターンの直後後には、DLL または KERNEL32 は、32 ビット サンクの GP 違反を表示場合、ターゲット関数が _stdcall として宣言されることおよび、DS、ES、FS、SS、EBP、EBX、ESI、または EDI レジスタを変更していないことを確認します。 C または C++ コードは、レジスタを変更するを行いませんが、アセンブリ言語コードを慎重にチェックされる必要があります。
  6. 確認してください、無効な場所へ返します対象者を対象に Win16 ベース場合宣言あり FAR として定義されています。 これは小さなモデル DLL の特に重要なので、中規模および大規模のモデルの DLL の関数は、FAR 既定では。
  7. 64 KB を (つまり、thunked のポインター) をパラメーターとして渡されたポインターからのデータの複数の Win16 ベースの関数をアクセスするときに、GP フォールトが発生する、する場合のタイル化されたセレクターは、配列を割り当て、次の資料「サポート技術情報」(Microsoft Knowledge Base) で。
    132005DOCERR: AllocSelector & FreeSelector ドキュメントが完全ではありません。
    常 Win16 側では、thunked のポインターにから構成されます、単一のセレクターのつまり巨大なポインターとして使用することはできません、64 K の制限値。 データ ポインターのアドレスの全体元範囲を参照するタイル化されたセレクターの配列を作成していて巨大なポインター変数データへのアクセスに使用する場合にのみが Win16 ベースのターゲット DLL - にアクセスします。
  8. サンクのコンテキストでのみ thunked のポインターを使用するようにします。 Win16 ベースのターゲットで使用するためには、サンク コンパイラによって割り当てられたセレクターは、サンク返します直ちに解放されます。
  9. 取得していることを確認するには、対象関数の先頭にブレークポイントを配置します。 ターゲット側、サンクのとは独立してをデバッグしたおよびターゲット内のエラーは発生し確率は、ターゲットが行うサンクをで実行できないものかが存在しないメモリを参照することは良い。 手順 7 および 8 参照してください。

プロパティ

文書番号: 133722 - 最終更新日: 2005年7月11日 - リビジョン: 2.3
この資料は以下の製品について記述したものです。
  • Microsoft Platform SDK January 2000 Edition?を以下の環境でお使いの場合
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows Millennium Edition
キーワード:?
kbhowto kbprogramming kbkernbase kbmt KB133722 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:133722
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com