2012-10-10 15 views
54

wiem, że mogę wpisać print someFloatVariable kiedy ustawić punkt przerwania lub po [self someIvarHoldingAnObject], ale nie mogę robić pożyteczne rzeczy jak:Jak wywoływać metody lub wykonywać kod w debugerze LLDB?

[self setAlpha:1]; 

Wtedy to wypluwa:

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

Weird rzeczą jest to, że można zadzwonić pod numer po [self someIvarHoldingAnObject] i wydrukować jego opis.

Wydaje mi się, że widziałem wideo sprzed roku, w którym ktoś pokazał, jak wykonać kod za pomocą konsoli w czasie wykonywania, a jeśli się nie mylę, ten facet dostarczył argumenty i przypisane obiekty do wskaźników. Jak to zrobić?

+0

Istnieje przykład [w lldb-for-gdb-users.txt] (http://opensource.apple.com/source/lldb/lldb-69/docs/lldb-for-gdb-users.txt) dla C: 'expr (int) printf (" ... ")'. Może powinieneś poprzedzić inwokację metody za pomocą 'wyraż (typ)'? – osgx

Odpowiedz

85

Kanoniczna odniesienie do poleceń lldb gdb v. Jest http://lldb.llvm.org/lldb-gdb.html

Chcesz użyć polecenia expr rozpoznawaną wyrażenia. Jest to jedno z poleceń lldb, które oprócz argumentów pobiera "surowe dane wejściowe", więc często potrzebujesz "-", aby wskazać, gdzie kończą się argumenty (do expr) i zaczynają się polecenia. na przykład

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

Istnieje skrót "p", który wykonuje - dla Ciebie (ale nie pozwala na żadne argumenty), np.

(lldb) p [self setAlpha:1] 

Jeśli funkcja (e) dzwonisz nie są częścią programu, będziesz często trzeba jawnie zadeklarować typ zwracany tak lldb wie, jak je nazwać. na przykład

(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) 

Istnieje prosty sposób na obejście problemu z argumentem zmiennoprzecinkowym, BTW. Tworzysz plik "prefiks wyrażeń", który jest dodawany do każdego wyrażenia wprowadzonego w lldb, wraz z prototypem twoich metod klasy. Na przykład, mam klasę MyClass, która dziedziczy po NSObject, ma dwie interesujące metody: "setArg:" i "getArg", które ustawiają i otrzymują float ivar. To jest głupi mały przykład, ale pokazuje, jak z niego korzystać. Oto plik prefix pisałem dla lldb:

@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 *); 
} 

w moim pliku ~/.lldbinit dodam

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

i teraz mogę zrobić

(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 

Zauważysz włączyłem parę standardowe funkcje biblioteki C tutaj. Po wykonaniu tej czynności nie muszę już przesyłać typów zwracanych, np.

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

(. Poprawka do tego "< bez rezultatu >" sprawa została zaangażowana do źródeł lldb TOT już)

+0

wyraż - [self setAlpha: 0,5f] lub expr - [self setAlpha: 1] oba powodują, że dany widok całkowicie zniknie z ekranu. Wygląda na to, że coś się dzieje, ale zdecydowanie nie jest to właściwe. Mogę pisać tylko te komendy, gdy ustawiam punkt przerwania. Czy jest jakiś sposób na zrobienie takich rzeczy, podczas gdy kod nadal działa/zwalnia? –

+0

Nie, proces ten należy zatrzymać po wywołaniu tej metody. Jeśli ten selektor przyjmuje typ zmiennoprzecinkowy, istnieje niedociągnięcie, które może wystąpić przy pomocy lldb Xcode 4.5 - jeśli argument funkcji przyjmuje typ zmiennopozycyjny i nie masz informacji debugowania, lldb nie daje ci żadnej możliwości przekazać wartość jako float. Przekaże ją jako podwójną bezwarunkową, zgodnie ze starym, nie-prototypowym zasadami promocji argumentów językowych. Jeśli lldb ma informacje debugowania dla tej klasy, powinno być w stanie zrobić to, co trzeba. Wiele przypadków tego problemu w programowaniu ObjC zostanie naprawionych w przyszłej wersji. –

+0

NB: Jeśli trafisz na problem, który miałem na myśli przy użyciu opcji float v. Double, wartość, którą przekazujesz do setAlpha, nie będzie taka, jakiej oczekujesz, będzie to pewna losowo wyglądająca, zwariowana liczba, która może być bardzo bliska 0, na przykład. –

2

Jeśli potrzebujesz multilinii, użyj expression:

expression 

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

// code will execute now 

Blank linia, aby zakończyć i wykonać kod.

Powiązane problemy