Pergunta

Em MSVC, DebugBreak () ou __ DebugBreak causa um depurador para quebrar. Em x86 é equivalente a escrever "_asm int 3", em x64 é algo diferente. Ao compilar com gcc (ou qualquer outro compilador padrão) eu quero fazer uma pausa no depurador também. Existe uma função independente de plataforma ou intrínseca? Eu vi o XCode questão sobre isso, mas ele doesn' t parecem bastante portátil.

Sidenote: Eu quero principalmente para implementar ASSERT com isso, e eu entendo que eu posso usar assert () para isso, mas eu também quero escrever DEBUG_BREAK ou algo no código

.
Foi útil?

Solução

O que sobre a definição de uma macro condicional com base em #ifdef que se expande para diferentes construções baseado na arquitetura ou plataforma atual.

Algo como:

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

Este seria expandida pelo pré-processador a instrução depurador quebra correta baseado na plataforma onde o código é compilado. Desta forma, você sempre use DEBUG_BREAK em seu código.

Outras dicas

Um método que é portável para a maioria dos sistemas POSIX é a seguinte:

raise(SIGTRAP);

GCC tem uma função interna chamada __builtin_trap que você pode ver aqui , no entanto, assume-se que pára a execução de código Uma vez que este é alcançado.

você deve garantir que a chamada __builtin_trap() é condicional, caso contrário, nenhum código será emitido depois.

este post alimentada por todos os 5 minutos de teste, YMMV.

Isto parece uma biblioteca compat apropriado https://github.com/scottt/debugbreak

Acabei de adicionar um módulo para portátil de trechos (uma coleção de trechos de domínio público de código portátil) para fazer isso. Não é 100% portátil, mas deve ser bastante robusto:

  • __builtin_debugtrap para algumas versões do clang (identificado com __has_builtin(__builtin_debugtrap))
  • Em MSVC e Intel C ++ Compiler C /: __debugbreak
  • Para ARM C C ++ Compiler /: __breakpoint(42)
  • Para x86 / x86_64, montagem: int $03
  • Para ARM Thumb, montagem: .inst 0xde01
  • Para ARM AArch64, montagem: .inst 0xd4200000
  • Para outro braço, montagem: .inst 0xe7f001f0
  • Para Alpha, montagem: bpt
  • Para C não-hospedado com GCC (ou algo que se disfarça como ele), __builtin_trap
  • Caso contrário, incluem signal.h e
    • Se defined(SIGTRAP) (ou seja, POSIX), raise(SIGTRAP)
    • Caso contrário, raise(SIGABRT)

No futuro, o módulo no portátil de trechos podem expandir para incluir outra lógica e eu provavelmente vou esquecer de atualizar esta resposta, então você deve olhar lá para atualizações. É de domínio público (CC0), tão à vontade para roubar o código.

Se você considerar assert (x) o suficiente portátil, assert (false) parece ser a solução portátil óbvia para o problema.

Se você está tentando depurar uma condição relacionada com o acidente, o bom e velho abort moda () irá dar-lhe uma pilha de chamadas na maioria das plataformas. Desvantagem é que você não pode continuar a partir do PC atual, que você provavelmente não quer fazer de qualquer maneira.

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

Em vez de utilizar quebras 'normais' de depuração, por que não usar um dos seguintes, como uma divisão por zero:

int iCrash = 13 / 0;

ou dereference um ponteiro NULL:

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

Pelo menos esta é portátil accross muitas plataformas / arquiteturas.

Em muitos depuradores você pode especificar qual ação você deseja realizar sobre o que exceções para que possa agir em conformidade quando um dos itens acima é atingido (como a execução de pausa, ala um "int 3" instrução) e uma exceção é gerada.

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

Quando o processo está dormindo, você pode anexar um depurador ao processo, altere a b variável para quebrar o ciclo e fazer a sua coisa. Este código pode não funcionar em uma compilação otimizada!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top