2010-12-01 4 views
80

Wie kann ich programmtechnisch einen Breakpoint in C- oder C++ - Code setzen, der unter Linux für gdb funktioniert?Breakpoint in C- oder C++ - Code programmgesteuert für gdb auf Linux setzen

d.h .:

int main(int argc, char** argv) 
{ 
    /* set breakpoint here! */ 
    int a = 3; 
    a++; /* In gdb> print a; expect result to be 3 */ 
    return 0; 
} 
+7

Sehr viel eine Randnotiz (sorry nitpick), aber wenn Sie über Portabilität besorgt sind, dann sind Sie wahrscheinlich auch besorgt über Korrektheit - daher "int main" anstatt "void main". –

+0

@Stuart - Fest. Sollte das vor einer Weile getan haben. –

+3

@ J.Polfer: Die 'return 0' ist allerdings nicht notwendig und ist nur Rauschen! –

Antwort

77

Eine Möglichkeit ist, um eine Unterbrechung zu signalisieren:

#include <csignal> 

// Generate an interrupt 
std::raise(SIGINT); 

In C:

#include <signal.h> 
raise(SIGINT); 

UPDATE: MSDN states, das Windows nicht wirklich SIGINT unterstützen, so dass, wenn Portabilität ist ein Anliegen, Sie sind wahrscheinlich besser dran mit SIGABRT.

+0

Das ist tragbarer, oder? –

+0

Ja, dies sollte über Betriebssysteme/Compiler/Debugger hinweg funktionieren. –

+1

Ich kenne keine anderen Debugger, aber gdb ist ziemlich flexibel in der [Signalverarbeitung] (http://www.delorie.com/gnu/docs/gdb/gdb_39.html). – Cascabel

18

von here suchen, fand ich die folgende Art und Weise:

void main(int argc, char** argv) 
{ 
    asm("int $3"); 
    int a = 3; 
    a++; // In gdb> print a; expect result to be 3 
} 

Dies scheint ein Hauch hackish mir. Und ich denke, das funktioniert nur auf x86-Architektur.

+3

Und nur mit Compilern, die die AT & T Assembly-Syntax unterstützen. Insbesondere der Compiler von Microsoft ('cl.exe') unterstützt diese Syntax nicht, sondern verwendet eine andere Syntax. –

+0

Die Frage war über Linux, also können wir annehmen, dass die gcc-Syntax für x86 funktioniert. –

+0

BTW - Ich habe das oben auf meiner x86-Maschine versucht und es hat funktioniert. Ich war neugierig, ob es einen besseren Weg dafür gab. Sieht so aus als wäre es. –

25

In einem Projekt arbeite ich an, wir tun dies.

raise(SIGABRT); /* To continue from here in GDB: "signal 0". */ 

(In unserem Fall haben wir hart, wenn dies geschehen ist außerhalb des Debuggers, Erzeugen eines Crash-Bericht, wenn möglich, das ist ein Grund, warum wir früher zum Absturz bringen wollten .. SIGABRT Dadurch portably über Windows, Mac und Linux nahm mehrere Versuche Wir mit ein paar #ifdefs endete, helfend hier kommentiert:. http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66)

+2

Wie üblich sieht Windows nicht wie die anderen aus :) – mathk

+0

Ist es möglich, "Signal 0" auszugeben, um das Programm in einem angehaltenen Zustand zu programmieren? Es wäre schön, von diesem Punkt aus "n" oder "s" verwenden zu können, ohne dass ein "c" ausgegeben wird. –

+1

@JasonDoucette Wenn Sie nur wollen, dass das Programm pausiert, möchten Sie vielleicht eine 'breakpoint()' Funktion in Ihrem Programm hinzufügen (es kann leer sein oder nur eine print-Anweisung enthalten) und 'break breakpoint' zu Ihrem' ~ hinzufügen/.gdbinit'. –

9

__asm__("int $3"); sollte funktionieren:

int main(int argc, char** argv) 
{ 
    /* set breakpoint here! */ 
    int a = 3; 
    __asm__("int $3"); 
    a++; /* In gdb> print a; expect result to be 3 */ 
    return 0; 
} 
+0

Super, danke! – leishman

+1

Ich definiere das gerne, damit ich mich nicht an die Syntax erinnern muss. Ich habe es überall in meinem Code gestreut, manchmal anstelle von 'assert()', da ich den debugger stoppe, lasst mich alle Variablen und den Stapel untersuchen. Und natürlich, wie behauptet, muss ich es nicht für Produktionscode entfernen – Mawg

1

Unter OS X können Sie einfach anrufen std::abort() (es könnte das gleiche auf Linux sein)

+0

Welche Bibliothek? – Alex

Verwandte Themen