Существует ли переносимый эквивалент DebugBreak()/__debugbreak?

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

  •  05-07-2019
  •  | 
  •  

Вопрос

В MSVC, Отладочный перерыв() или __дебагбрейк приведет к поломке отладчика.На x86 это эквивалентно написанию "_asm int 3", на x64 это что-то другое.При компиляции с помощью gcc (или любого другого стандартного компилятора) Я также хочу выполнить взлом в debugger.Существует ли функция, не зависящая от платформы, или она встроена в нее?Я видел, как Вопрос по XCode примерно так, но это кажется недостаточно портативным.

Побочное примечание:В основном я хочу реализовать ASSERT с этим, и я понимаю, что могу использовать assert () для этого, но я также хочу написать DEBUG_BREAK или что-то еще в коде.

Это было полезно?

Решение

Как насчет определения условного макроса на основе #ifdef, который расширяется до различных конструкций на основе текущей архитектуры или платформы.

Что-то вроде:

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

Это будет расширено препроцессором до правильной инструкции прерывания отладчика, основанной на платформе, где компилируется код. Таким образом, вы всегда используете DEBUG_BREAK в своем коде.

Другие советы

Метод, который переносим для большинства систем POSIX:

raise(SIGTRAP);

GCC имеет встроенную функцию с именем __buildin_trap , которую вы можете увидеть здесь , однако предполагается, что выполнение кода останавливается, как только это будет достигнуто.

вы должны убедиться, что вызов __ builtin_trap () является условным, в противном случае после него код не будет выдан.

этот пост подпитывается всеми 5 минутами тестирования, YMMV.

Это похоже на соответствующую библиотеку для сравнения https://github.com/scottt/debugbreak

Я просто добавил модуль Для переносимые фрагменты (набор общедоступных фрагментов переносимого кода) для этого.Он не переносится на 100%, но должен быть довольно надежным:

  • __builtin_debugtrap для некоторых версий clang (идентифицируемых с __has_builtin(__builtin_debugtrap))
  • На MSVC и компиляторе Intel C / C ++: __debugbreak
  • Для компилятора ARM C / C ++: __breakpoint(42)
  • Для x86/x86_64 сборка: int $03
  • Для Большого пальца РУКИ в сборе: .inst 0xde01
  • Для ARM AArch64, сборка: .inst 0xd4200000
  • Для другого РЫЧАГА в сборе: .inst 0xe7f001f0
  • Для Alpha, сборка: bpt
  • Для не размещенного C с GCC (или чего-то, что маскируется под него), __builtin_trap
  • В противном случае включите signal.h и
    • Если defined(SIGTRAP) (т.е. POSIX), raise(SIGTRAP)
    • В противном случае, raise(SIGABRT)

В будущем модуль в portable-snippets может расшириться, чтобы включить другую логику, и я, вероятно, забуду обновить этот ответ, поэтому вам следует поискать там обновления.Это общественное достояние (CC0), так что не стесняйтесь украсть код.

Если вы считаете assert (x) достаточно переносимым, assert (false) кажется очевидным переносимым решением вашей проблемы.

Если вы пытаетесь отладить состояние, связанное с падением, старый добрый abort () даст вам стек вызовов на большинстве платформ. Недостатком является то, что вы не можете продолжить работу с текущего ПК, что вам, вероятно, не стоит делать в любом случае.

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

Вместо использования «нормальных» разрывов отладки, почему бы не использовать одно из следующего, например деление на ноль:

int iCrash = 13 / 0;

или разыменуйте нулевой указатель:

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

По крайней мере, это переносимо для многих платформ / архитектур.

Во многих отладчиках вы можете указать, какое действие вы хотите выполнить с какими исключениями, чтобы вы могли действовать соответствующим образом, когда выполняется одно из вышеперечисленных действий (например, выполнение паузы, инструкция «int 3») и генерируется исключение.

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

Когда процесс находится в спящем режиме, вы можете присоединить к нему отладчик, изменить переменную b, чтобы разорвать цикл и сделать свое дело. Этот код может не работать в оптимизированной сборке!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top