2009-08-30 6 views
19

Ich frage mich, warum Evaluierungsfunktion in Gdb nicht funktioniert? In meiner Quelldatei, die ich beim Debuggen in gdb einbeziehe, sind diese Beispiele falsche Auswertungen.Wie bewertet man Funktionen in GDB?

(gdb) p pow(3,2) 

$10 = 1 

(gdb) p pow(3,3) 

$11 = 1 

(gdb) p sqrt(9) 

$12 = 0 

Antwort

14

Meine Vermutung ist, dass der Compiler und Linker Magie mit diesen besonderen Funktionen mag. Am wahrscheinlichsten, um Leistung zu erhöhen.

Wenn Sie unbedingt pow() müssen in gdb zur Verfügung stehen, dann können Sie Ihre eigenen Wrapper-Funktion erstellen:

double mypow(double a, double b) 
{ 
    return pow(a,b); 
} 

Vielleicht ist es auch wickeln in eine #ifdef DEBUG oder etwas nicht das letzte binäre Unordnung.

BTW, werden Sie feststellen, dass andere Bibliotheksfunktionen aufgerufen werden können (und deren Rückgabewert gedruckt), zum Beispiel:

(gdb) print printf("hello world") 
$4 = 11 
+0

Die richtige Antwort wird unten von anon gegeben – mattypiper

15

Die Syntax für eine Funktion in gdb Aufruf ist

call pow(3,2) 

Typ

help call 

an der GDB Eingabeaufforderung für weitere Informationen.

+0

Danke! Aber Anruf ist immer noch nicht richtig (GDB) -Aufruf sqrt (9) $ 14 = 0 (GDB) -Aufruf pow (3,3) 15 $ = 1 – Tim

+1

Druck arbeiten, werden auch Funktionen aufrufen. In der Tat, ich denke, der einzige Unterschied ist, dass Anruf nicht die Ausgabe durcheinander bringt, wenn void Funktionen –

0
NAME 
    pow, powf, powl - power functions 

SYNOPSIS 
    #include <math.h> 

    double pow(double x, double y); 

Sie sollten nicht einen int in den Ort eines Doppel

call pow(3. , 2.) 

auch passieren, ist nicht genug, um ein einziges Argument übergeben, müssen Sie zwei Argumente wie die Funktion

wrong: call pow (3.) 
erwartet
+1

tatsächlich aufgerufen wird, Übergabeintes funktionieren gut. nicht sicher, ob es nur Zufall ist, aber Mypow (siehe meine Antwort) mit Ganzzahlen aufzurufen, ergibt das richtige Ergebnis. Ich bekomme keine Ausgabe von gdb, wenn ich pow (2.0.2.0) anrufe, aber ich tue, wenn ich mypow() mit irgendwelchen Nummern anrufe –

4

Eigentlich zumindest auf meinem Linux-Implementierung von gcc, viele der mathematischen Funktionen werden durch Varianten ersetzt, die für die Typen ihrer Argumente durch einige ausgefallene Substitutionen durch math.h und bits/mathcalls.h (enthalten innerhalb von math.h) ersetzt werden. Als Konsequenz werden Funktionen wie pow und exp stattdessen als __pow oder *__GI___exp aufgerufen (Ihre Ergebnisse können je nach Art der Argumente und vielleicht der jeweiligen Version variieren).

Um zu identifizieren, was genau die Funktion ist, die in meinem Code verknüpft ist, legte ich eine Pause an einer Zeile, wo genau diese Funktion aufgerufen wird, z. habe eine Zeile in meinem Code mit b=exp(c);. Dann laufe ich bis zu diesem Unterbrechungspunkt in gdb und benutze dann den "step" -Befehl, um den Anruf von dieser Leitung aus einzugeben. Dann kann ich den "where" -Befehl verwenden, um den Namen der aufgerufenen Routine zu identifizieren. In meinem Fall war das *__GI___exp.

Es gibt wahrscheinlich klügere Möglichkeiten, diese Informationen zu erhalten, aber ich konnte den richtigen Namen nicht finden, nur durch Ausführen des Präprozessors allein (die Option -E) oder durch den Assembly-Code generiert (-s).

+2

Ich weiß, das ist alt, aber wenn jemand kommt, geht hier: Für mich funktionierte es nur 'p pow', was mir folgendes gab:' $ 28 = {} 0x7ffff77ffbd0 ' – falstro

14

Sie müssen gdb mitteilen, dass es den Rückgabewert in den Fließkomma-Registern finden wird, nicht die normalen, zusätzlich zu den Parametern die richtigen Typen.

d.h .:

(GDB) p ((Doppel (*)()) pow) (2, 2.

)

$ 1 = 4

+0

Das ist seltsam, ich bekomme einen Wert von $ 1 = 2 – daj

2

pow als Makro definiert, keine Funktion. Der Aufruf in gdb kann nur Funktionen in Ihrem Programm oder in einer gemeinsam genutzten Bibliothek aufrufen. Daher sollte der Aufruf von pow in gdb fehlschlagen.

(gdb) p pow(3,2) 
    No symbol "pow" in current context. 

hier ist der gcc Binärcode Quelle Aufruf pow erzeugt (int, int):

(gdb) list 
    1  int main() { 
    2  int a=pow(3,2); 
    3  printf("hello:%d\n", a); 
    4  } 
    (gdb) x/16i main 
    0x4004f4 <main>:  push %rbp 
    0x4004f5 <main+1>: mov %rsp,%rbp 
    0x4004f8 <main+4>: sub $0x10,%rsp 
    0x4004fc <main+8>: movl $0x9,-0x4(%rbp) 
    => 0x400503 <main+15>: mov -0x4(%rbp),%eax 
    0x400506 <main+18>: mov %eax,%esi 
    0x400508 <main+20>: mov $0x40060c,%edi 
    0x40050d <main+25>: mov $0x0,%eax 
    0x400512 <main+30>: callq 0x4003f0 <[email protected]> 
    0x400517 <main+35>: leaveq 
    0x400518 <main+36>: retq 
    0x400519: nop 
    0x40051a: nop 
    0x40051b: nop 
    0x40051c: nop 
    0x40051d: nop 

hier ist der gcc Binärcodes Quelle Aufruf pow (float, float) erzeugt:

(gdb) list 
    1  int main() { 
    2  double a=pow(0.3, 0.2); 
    3  printf("hello:%f\n", a); 
    4  } 
    (gdb) x/16i main 
    0x4004f4 <main>:  push %rbp 
    0x4004f5 <main+1>: mov %rsp,%rbp 
    0x4004f8 <main+4>: sub $0x10,%rsp 
    0x4004fc <main+8>: movabs $0x3fe926eff16629a5,%rax 
    0x400506 <main+18>: mov %rax,-0x8(%rbp) 
    0x40050a <main+22>: movsd -0x8(%rbp),%xmm0 
    0x40050f <main+27>: mov $0x40060c,%edi 
    0x400514 <main+32>: mov $0x1,%eax 
    0x400519 <main+37>: callq 0x4003f0 <[email protected]> 
    0x40051e <main+42>: leaveq 
    0x40051f <main+43>: retq