2012-10-10 4 views
54

Ich weiß, ich kann print someFloatVariable geben, wenn ich einen Haltepunkt gesetzt oder po [self someIvarHoldingAnObject], aber ich kann nützliche Dinge nicht tun:Wie Methoden aufrufen oder Code in LLDB Debugger ausführen?

[self setAlpha:1]; 

es dann spuckt:

error: '[self' is not a valid command.

Seltsame ist, dass ich kann po [self someIvarHoldingAnObject] anrufen und es wird seine Beschreibung drucken.

Ich glaube, ich habe vor einem Jahr ein Video gesehen, wo jemand gezeigt hat, wie man Code über die Konsole zur Laufzeit ausführt, und wenn ich mich nicht täusche, lieferte dieser Typ auch Argumente und zugewiesene Objekte an Zeiger. Wie geht das?

+0

Es ist ein Beispiel [in LLDB-for-GDB-users.txt] (http://opensource.apple.com/source/lldb/lldb-69/docs/lldb-for-gdb-users.txt) für C: 'expr (int) printf (" ... ")'. Vielleicht sollten Sie Ihren Methodenaufruf mit 'expr (type)' voranstellen? – osgx

Antwort

85

Die kanonische Referenz für GDB v. LLDB Befehle ist http://lldb.llvm.org/lldb-gdb.html

Sie wollen den Befehl expr verwenden, die einen Ausdruck auswertet. Es ist eines der LLDB Befehle, die „raw input“ neben Argumenten übernehmen, so dass Sie oft brauchen „-“, um anzuzeigen, wo die Argumente (bis expr) Ende und der Befehl (n) beginnen. z.B.

(lldb) expr -- [self setAlpha:1] 

Es gibt eine Abkürzung, "p", die die - für Sie tut (aber keine Argumente erlaubt), z.

(lldb) p [self setAlpha:1] 

Wenn die Funktion (en) Sie ist nicht Teil des Programms anrufen, müssen Sie oft explizit ihren Rückgabetyp erklären, so LLDB weiß, wie sie nennen. z.B.

(lldb) p printf("hi\n") 
error: 'printf' has unknown return type; cast the call to its declared return type 
error: 1 errors parsing expression 
(lldb) p (int)printf("hi\n") 
(int) $0 = 3 
hi 
(lldb) 

Es gibt eine nette Möglichkeit, das Problem mit dem Gleitkomma-Argument zu umgehen, BTW. Sie erstellen eine "Ausdruckspräfix" -Datei, die zu jedem Ausdruck, den Sie in lldb eingeben, mit einem Prototyp Ihrer Klassenmethoden hinzugefügt wird. Zum Beispiel habe ich eine Klasse MyClass, die von NSObject erbt, es hat zwei Methoden von Interesse, "setArg:" und "getArg", die setzen und ein float ivar erhalten. Dies ist ein albernes kleines Beispiel, aber es zeigt, wie man es benutzt. Hier ist eine Präfixdatei ich für LLDB schrieb:

@interface NSObject 
@end 
@interface MyClass : NSObject 
- init; 
- setArg: (float)arg; 
- (float) getArg; 
@end 

extern "C" { 
    int strcmp (const char *, const char *); 
    int printf(const char * __restrict, ...); 
    void puts (const char *); 
} 

in meiner ~/.lldbinit Datei I

settings set target.expr-prefix /Users/jason/lldb-prefix.h 

hinzufügen und jetzt kann ich

(lldb) p [var getArg] 
(float) $0 = 0.5 
(lldb) p [var setArg:0.7] 
(id) $1 = 0x0000000100104740 
(lldb) p [var getArg] 
(float) $2 = 0.7 

Sie werden bemerken, ich eingeschlossen, ein paar Standard-C-Bibliothek funktioniert auch hier. Nachdem ich dies getan habe, muss ich die Rückgabetypen von diesen nicht mehr zaubern, z.

(lldb) p printf("HI\n") 
<no result> 
HI 
(lldb) p strcmp ("HI", "THERE") 
(int) $3 = -12 

(a. Fix für das "< kein Ergebnis >" Sache bereits an die LLDB TOT Quellen begangen wurde)

+0

expr - [self setAlpha: 0.5f] oder expr - [self setAlpha: 1] beide lassen die fragliche Ansicht vollständig vom Bildschirm verschwinden. Es scheint, als würde etwas passieren, aber definitiv nicht das Richtige. Ich kann diese Befehle nur eingeben, wenn ich einen Haltepunkt einstelle. Oder gibt es eine Möglichkeit, solche Dinge zu tun, während der Code noch läuft/nicht pausiert? –

+0

Nein, Sie müssen den Prozess stoppen, wenn Sie diese Methode aufrufen. Wenn dieser Selektor einen Float-Typ annimmt, gibt es einen Fehler, den Sie möglicherweise mit der lldb von Xcode 4.5 treffen - wenn das Funktionsargument einen Float-Typ annimmt und Sie keine Debug-Informationen haben, gibt Ihnen lldb keinen Weg dazu Übergeben Sie den Wert als Float. Es wird es bedingungslos als ein Double übergeben, wobei es den alten Regeln der C-Sprache, die keine Prototyp-Argumente sind, folgt. Wenn lldb Debug-Informationen für diese Klasse enthält, sollte es in der Lage sein, das Richtige zu tun. Viele Fälle dieses Problems in der ObjC-Programmierung werden in einer zukünftigen Version behoben. –

+0

NB: Wenn Sie das Problem mit float v. Double schlagen, wird der Wert, den Sie an Ihre setAlpha übergeben, nicht das sein, was Sie erwarten, es wird irgendeine zufällig aussehende verrückte Zahl sein, die sehr nahe bei 0 liegt. zum Beispiel. –

2

Wenn Sie mehrzeilige benötigen, verwenden expression:

expression 

do { 
    try thing.save() 
} catch { 
    print(error) 
} 

// code will execute now 

Blank Zeile, um den Code zu beenden und auszuführen.