Gibt es ein portables Äquivalent zu DebugBreak()/__debugbreak?

Lesezeit: 5 Minuten

Gibt es ein portables Aquivalent zu DebugBreak debugbreak
lebendige

Im MSVC, DebugBreak() oder __debugbreak einen Debugger zum Abbruch bringen. Auf x86 entspricht es dem Schreiben von “_asm int 3”, auf x64 ist es etwas anderes. Beim Kompilieren mit gcc (oder einem anderen Standard-Compiler) möchte ich auch einen Einbruch in den Debugger machen. Gibt es eine plattformunabhängige oder intrinsische Funktion? Ich habe die XCode-Frage dazu gesehen, aber sie scheint nicht portabel genug zu sein.

Nebenbemerkung: Ich möchte damit hauptsächlich ASSERT implementieren, und ich verstehe, dass ich assert() dafür verwenden kann, aber ich möchte auch DEBUG_BREAK oder etwas in den Code schreiben.

Eine Methode, die auf die meisten POSIX-Systeme portierbar ist, ist:

raise(SIGTRAP);

  • raise(SIGTRAP) funktionierte perfekt für mich auf gcc/Linux. __builtin_trap() verursacht a SIGILL Signal angehoben werden.

    – Benutzer666412

    3. Oktober 12 um 17:28 Uhr


  • Kann dies unter OSX verwendet werden? Ich habe dies in Xcode 6.1 versucht, sagte ich SIGTRAP war eine nicht deklarierte Kennung.

    – Thomm

    4. März 15 um 15:47 Uhr

  • @thomthom: Hast du #include <signal.h> ?

    – Café

    5. März 15 um 0:39 Uhr

  • Nein – das hatte ich übersehen. Habe das später herausgefunden. Habe vergessen meinen Kommentar zu löschen.

    – Thomm

    7. März 15 um 10:43 Uhr

  • Funktioniert bei mir: für iOS, macOS, tvOS und Android.

    – Peter

    4. November 20 um 17:12 Uhr

Gibt es ein portables Aquivalent zu DebugBreak debugbreak
nemequ

Ich habe gerade hinzugefügt ein Modul zu Portable-Snippets (eine Sammlung von Public-Domain-Snippets von portablem Code), um dies zu tun. Es ist nicht 100% tragbar, aber es sollte ziemlich robust sein:

  • __builtin_debugtrap für einige Versionen von clang (identifiziert mit __has_builtin(__builtin_debugtrap))
  • Auf MSVC und Intel C/C++ Compiler: __debugbreak
  • Für ARM C/C++-Compiler: __breakpoint(42)
  • Für x86/x86_64, Montage: int3
  • Für ARM Thumb, Montage: .inst 0xde01
  • Für ARM AArch64, Montage: .inst 0xd4200000
  • Für andere ARM, Montage: .inst 0xe7f001f0
  • Für Alpha, Montage: bpt
  • Für nicht gehostetes C mit GCC (oder etwas, das sich als solches ausgibt), __builtin_trap
  • Ansonsten einschließen signal.h und
    • Wenn defined(SIGTRAP) (dh POSIX), raise(SIGTRAP)
    • Ansonsten, raise(SIGABRT)

In Zukunft wird das Modul in portablen Snippets möglicherweise um andere Logik erweitert, und ich werde wahrscheinlich vergessen, diese Antwort zu aktualisieren. Sie sollten also dort nach Updates suchen. Es ist gemeinfrei (CC0), also fühlen Sie sich frei, den Code zu stehlen.

  • Für x86 (einschließlich x86-64) GAS-Syntax ist es besser zu schreiben int3 um deutlich zu machen, dass Sie den Sonderfall-Debug-Break-Befehl, ein Byte, wollen CC nicht CD 03, für die seltenen Fälle, in denen dies von Bedeutung ist (Codegröße und v8086-Modus). (felixcloutier.com/x86/intn:into:int3:int1). Mit NASM bauen sie sich tatsächlich anders zusammen, GAS optimiert beides int3.

    – Peter Cordes

    26. August 2020 um 7:28 Uhr

  • __builtin_trap kompiliert normalerweise zu ud2 (x86) oder eine andere illegale Anweisung, kein Debug-Haltepunkt und wird auch als noreturn behandelt, Sie können danach nicht einmal mit einem Debugger fortfahren. Es gehört nicht in diese Liste. zB gibt es keine ret Anweisung nach der ud2 in einer einfachen Funktion, die es vor einem C verwendet return x Erklärung.

    – Peter Cordes

    26. August 2020 um 7:32 Uhr


  • Danke @PeterCordes, ich habe sowohl diese Antwort als auch meinen zu verwendenden Code aktualisiert int3. FWIW, sowohl GCC als auch Clang generieren int3, auch (zumindest mit -O3), was hier wirklich wichtig ist, da es um C++ geht, nicht um Assembly. Das klingt nach int3 ist jedoch richtiger, also kein Grund, es nicht zu “reparieren” 🙂

    – nemequ

    29. August 2020 um 1:16 Uhr

  • Für __debug_trap, ich bin mir nicht sicher, ob hier wirklich etwas getan werden kann. Sowohl im Kommentar als auch im verlinkten Code befindet es sich tief im Fallback-Territorium und wird nur aufgerufen, wenn alles andere fehlgeschlagen ist und es ist eine nicht gehostete Umgebung (in diesem Fall ist signal.h nicht verfügbar). Die AFAICT-Alternative ist entweder nichts oder ein Kompilierungsfehler. Wenn Sie einen Vorschlag zu anderen möglichen Alternativen haben, wäre ich sicherlich offen; Ich stimme zu, dass es suboptimal ist (daher seine Position als letzter Ausweg).

    – nemequ

    29. August 2020 um 1:22 Uhr

  • -O3 sollte selbst für den eingebauten Assembler von clang irrelevant sein. Das ist die Optimierungsstufe bei der Übersetzung von C++ in asm. Asm in Maschinencode (einschließlich für Asm, der von einer asm("") Template-String) ist ein wirklich separater Prozess für gcc und logisch getrennt für clang. Aber ja, int3 ist eine gute Idee; so geht das 0xCC zerlegt, und es ist eine genauere Darstellung dessen, was Sie wollen.

    – Peter Cordes

    29. August 2020 um 1:23 Uhr


1643141407 395 Gibt es ein portables Aquivalent zu DebugBreak debugbreak
Jörg Ferreira

Was ist mit der Definition eines bedingten Makros auf der Grundlage von #ifdef, das auf der Grundlage der aktuellen Architektur oder Plattform auf verschiedene Konstrukte erweitert wird.

Etwas wie:

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

Dies würde durch den Präprozessor um die korrekte Debugger-Break-Anweisung erweitert, basierend auf der Plattform, auf der der Code kompiliert wird. Auf diese Weise verwenden Sie immer DEBUG_BREAK in deinem Code.

GCC hat eine eingebaute Funktion namens __builtin_trap die du sehen kannst Hier, es wird jedoch davon ausgegangen, dass die Codeausführung angehalten wird, sobald dies erreicht ist.

Sie sollen dafür sorgen, dass die __builtin_trap() Der Aufruf ist bedingt, ansonsten wird danach kein Code ausgegeben.

Dieser Beitrag wurde von allen 5 Minuten Testzeit angeheizt, YMMV.

Dies sieht nach einer geeigneten Kompatibilitätsbibliothek aus https://github.com/scottt/debugbreak

Dies scheint eine sehr gute, tragbare Lösung für diese Frage zu sein:
https://github.com/scottt/debugbreak

Der im zitierten Repository bereitgestellte Header (debugbreak.h) kapselt MSVCs

    __debugbreak, 

und

    __asm__ volatile("int $0x03");

auf i386 und x86_64 und auf ARM implementiert es

    __asm__ volatile(".inst 0xe7f001f0");

sowie die Dokumentation einiger Problemumgehungen für Probleme, die im Header für das einmalige Überschreiten des Haltepunkts in GDB sowie ein Python-Skript zum Erweitern von GDB auf diesen Plattformen angegeben sind stepi oder Forts stecken bleiben. Das Skript fügt hinzu debugbreak-Schritt und debugbreak-fortsetzen zu GDB.

Wenn Sie bedenken assert(x) tragbar genug, assert(false) scheint die offensichtliche tragbare Lösung für Ihr Problem zu sein.

  • In den meisten Fällen gut, aber nicht so hilfreich bei der Freigabe von Code. Ja, manchmal muss ich Release-Code debuggen…

    Benutzer172783

    25. Oktober 11 um 13:54 Uhr


  • assert ist überhaupt keine geeignete Lösung, da es normalerweise nicht zulässt, dass das Programm weiter ausgeführt wird.

    – Benutzer7860670

    3. Januar 20 um 8:57 Uhr

.

636630cookie-checkGibt es ein portables Äquivalent zu DebugBreak()/__debugbreak?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy