Domanda

In MSVC, DebugBreak () o __ debugbreak causa l'interruzione di un debugger. Su x86 equivale a scrivere "_asm int 3", su x64 è qualcosa di diverso. Quando compilo con gcc (o qualsiasi altro compilatore standard), voglio fare anche una pausa nel debugger. Esiste una funzione indipendente dalla piattaforma o intrinseca? Ho visto la domanda XCode su questo, ma non lo fa ' non sembra abbastanza portatile.

Sidenote: principalmente voglio implementare ASSERT con quello, e capisco che posso usare assert () per quello, ma voglio anche scrivere DEBUG_BREAK o qualcosa nel codice.

È stato utile?

Soluzione

Che dire della definizione di una macro condizionale basata su #ifdef che si espande in diversi costrutti in base all'architettura o alla piattaforma corrente.

Qualcosa del tipo:

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

Questo sarebbe ampliato dal preprocessore con le istruzioni corrette di interruzione del debugger basate sulla piattaforma in cui viene compilato il codice. In questo modo usi sempre DEBUG_BREAK nel tuo codice.

Altri suggerimenti

Un metodo portatile per la maggior parte dei sistemi POSIX è:

raise(SIGTRAP);

GCC ha una funzione integrata chiamata __builtin_trap che puoi vedere qui , tuttavia si presume che l'esecuzione del codice si interrompe quando viene raggiunta.

tu dovresti assicurarti che la chiamata __builtin_trap () sia condizionata, altrimenti nessun codice verrà emesso dopo di essa.

questo post è stato alimentato da tutti e 5 i minuti di test, YMMV.

Sembra una libreria compatibile appropriata https://github.com/scottt/debugbreak

Ho appena aggiunto un modulo a snippet portatili (una raccolta di frammenti di codice portatile di dominio pubblico) per farlo. Non è portatile al 100%, ma dovrebbe essere piuttosto robusto:

  • __builtin_debugtrap per alcune versioni di clang (identificato con __has_builtin (__ builtin_debugtrap) )
  • Su MSVC e compilatore Intel C / C ++: __debugbreak
  • Per il compilatore ARM C / C ++: __breakpoint(42)
  • Per x86 / x86_64, assembly: int $ 03
  • Per pollice ARM, assembly: .inst 0xde01
  • Per ARM AArch64, assembly: .inst 0xd4200000
  • Per altri ARM, assembly: .inst 0xe7f001f0
  • Per Alpha, assembly: bpt
  • Per C non ospitato con GCC (o qualcosa che si maschera da solo), __builtin_trap
  • Altrimenti, includere signal.h e
    • Se definito (SIGTRAP) (ovvero POSIX), raise(SIGTRAP)
    • Altrimenti, raise(SIGABRT)

In futuro il modulo negli snippet portatili potrebbe espandersi per includere altra logica e probabilmente dimenticherò di aggiornare questa risposta, quindi dovresti cercare gli aggiornamenti. È di dominio pubblico (CC0), quindi sentiti libero di rubare il codice.

Se consideri assert (x) abbastanza portatile, assert (false) sembra essere la soluzione portatile ovvia al tuo problema.

Se si sta tentando di eseguire il debug di una condizione relativa all'arresto anomalo, il buon vecchio abort () ti darà uno stack di chiamate sulla maggior parte delle piattaforme. Il rovescio della medaglia è che non puoi continuare dal PC attuale, cosa che probabilmente non vorrai fare comunque.

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

Invece di utilizzare le interruzioni di debug "normali", perché non utilizzare uno dei seguenti, come una divisione per zero:

int iCrash = 13 / 0;

o dereference un puntatore NULL:

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

Almeno questo è portatile su molte piattaforme / architetture.

In molti debugger puoi specificare quale azione vuoi eseguire su quali eccezioni in modo da poter agire di conseguenza quando viene colpito uno di questi (come l'esecuzione di una pausa, un'istruzione " int 3 ") e viene generata un'eccezione.

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

Quando il processo è inattivo, è possibile collegare un debugger al processo, modificare la variabile b per interrompere il ciclo ed eseguire le operazioni. Questo codice potrebbe non funzionare in una build ottimizzata!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top