DebugBreak()/__debugbreak に相当する移植性の高いものはありますか?

StackOverflow https://stackoverflow.com/questions/173618

  •  05-07-2019
  •  | 
  •  

質問

MSVCでは、 デバッグブレーク() または __デバッグブレイク デバッガが壊れる原因となります。x86 では、「_asm int 3」を記述するのと同じですが、x64 では異なります。gcc (またはその他の標準コンパイラ) でコンパイルするときに、デバッガにもブレークインしたいと思います。プラットフォームに依存しない関数または組み込み関数はありますか?私が見ました XCodeの質問 それについてですが、移植性が十分ではないようです。

サイドノート:私は主に ASSERT を実装したいと考えており、そのためにassert() を使用できることは理解していますが、コードに DEBUG_BREAK などを書きたいとも考えています。

役に立ちましたか?

解決

現在のアーキテクチャまたはプラットフォームに基づいてさまざまな構造に拡張される #ifdef に基づいた条件付きマクロを定義する場合はどうでしょうか。

何かのようなもの:

#ifdef _MSC_VER
#define DEBUG_BREAK __debugbreak()
#else
...
#endif

これは、コードがコンパイルされるプラットフォームに基づいて、プリプロセッサによって正しいデバッガー ブレーク命令に拡張されます。いつも使っているこの方法 DEBUG_BREAK あなたのコードに。

他のヒント

ほとんどのPOSIXシステムに移植可能な方法は次のとおりです。

raise(SIGTRAP);

GCCには __ builtin_trap という名前の組み込み関数があり、こちら、ただし、これに達するとコードの実行が停止すると想定されています。

__ builtin_trap()の呼び出しが条件付きであることを確認する必要があります 、そうでない場合、その後にコードは出力されません。

この投稿は、5分間のすべてのテスト、YMMVによって強化されました。

これは適切な互換ライブラリのようです https://github.com/scottt/debugbreak

モジュール portable-snippets (ポータブルコードのパブリックドメインスニペットのコレクション)を実行します。 100%の移植性はありませんが、かなり堅牢である必要があります。

    cliの一部のバージョンの
  • __ builtin_debugtrap __ has_builtin(__ builtin_debugtrap)で識別)
  • MSVCおよびIntel C / C ++コンパイラ: __ debugbreak
  • ARM C / C ++コンパイラの場合: __ breakpoint(42)
  • x86 / x86_64の場合、アセンブリ: int $ 03
  • ARM Thumbの場合、アセンブリ: .inst 0xde01
  • ARM AArch64の場合、アセンブリ: .inst 0xd4200000
  • 他のARMの場合、アセンブリ: .inst 0xe7f001f0
  • Alphaの場合、アセンブリ: bpt
  • GCCを使用したホストされていないC(またはそれを装ったもの)の場合、 __ builtin_trap
  • それ以外の場合、 signal.h
    • defined(SIGTRAP)(つまりPOSIX)の場合、 raise(SIGTRAP)
    • それ以外の場合、 raise(SIGABRT)

将来、portable-snippetsのモジュールは他のロジックを含むように拡張される可能性があり、おそらくこの回答を更新するのを忘れるので、更新を確認する必要があります。パブリックドメイン(CC0)なので、コードを盗んでください。

assert(x)の移植性を十分に考慮している場合、assert(false)が問題に対する明白な移植性のあるソリューションのようです。

クラッシュ関連の状態をデバッグしようとしている場合、ほとんどのプラットフォームで古きよき形式のabort()が呼び出しスタックを提供します。欠点は、現在のPCから続行できないことです。これはおそらくとにかくしたくないでしょう。

http://www.cplusplus.com/reference/cstdlib/abort/

「通常の」デバッグブレークを使用する代わりに、ゼロ除算など、次のいずれかを使用してください。

int iCrash = 13 / 0;

またはNULLポインターの逆参照:

BYTE bCrash = *(BYTE *)(NULL);

少なくともこれは多くのプラットフォーム/アーキテクチャ間で移植可能です。

多くのデバッガーでは、どの例外に対してどのアクションを実行するかを指定できるため、上記のいずれかがヒットした場合(実行の一時停止、ala int 3命令など)に応じてアクションを実行し、例外が生成されます。

#define __debugbreak() \
do \
{       static bool b; \
        while (!b) \
                sleep(1); \
        b = false; \
} while (false)

プロセスがスリープ状態になったら、デバッガーをプロセスにアタッチし、変数bを変更してループを中断し、処理を実行できます。このコードは、最適化されたビルドでは機能しない可能性があります!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top