2012-10-10 18 views
54

Tôi biết tôi có thể gõ print someFloatVariable khi tôi đặt một breakpoint hoặc po [self someIvarHoldingAnObject], nhưng tôi không thể làm những việc hữu ích như:Làm thế nào để gọi các phương thức hoặc thực thi mã trong trình gỡ lỗi LLDB?

[self setAlpha:1]; 

Sau đó, nó spits ra:

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

điều Weird là tôi có thể gọi po [self someIvarHoldingAnObject] và nó sẽ in mô tả của nó. Tôi tin rằng tôi đã nhìn thấy một video một năm trước đây, nơi ai đó đã chứng minh làm thế nào để thực thi mã thông qua giao diện điều khiển trong thời gian chạy, và nếu tôi không nhầm anh chàng này cũng cung cấp các đối số và các đối tượng được giao cho con trỏ. Làm thế nào để làm điều đó?

+0

Có một ví dụ [trong lldb-for-gdb-users.txt] (http://opensource.apple.com/source/lldb/lldb-69/docs/lldb-for-gdb-users.txt) cho C: 'expr (int) printf (" ... ")'. Có thể bạn nên tiền tố lời gọi phương thức của bạn với 'expr (type)'? – osgx

Trả lời

85

Các tài liệu tham khảo kinh điển cho các lệnh LLĐB gdb v. Là http://lldb.llvm.org/lldb-gdb.html

Bạn muốn sử dụng lệnh expr mà đánh giá một biểu thức. Đó là một trong các lệnh lldb có "đầu vào thô" ngoài các đối số, do đó bạn thường cần một "-" để chỉ ra nơi các đối số (để expr) kết thúc và lệnh (s) bắt đầu. ví dụ.

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

Có phím tắt, "p", có phím tắt - cho bạn (nhưng không cho phép bất kỳ đối số nào), ví dụ:

(lldb) p [self setAlpha:1] 

Nếu (các) hàm bạn đang gọi không phải là một phần của chương trình, bạn thường cần khai báo rõ ràng loại trả về để lldb biết cách gọi. ví dụ.

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

Có một cách gọn gàng để giải quyết vấn đề đối số dấu chấm động, BTW. Bạn tạo một "tiền tố biểu thức" tập tin được thêm vào mỗi biểu thức bạn nhập vào lldb, với một nguyên mẫu của phương pháp lớp học của bạn. Ví dụ, tôi có một lớp MyClass mà kế thừa từ NSObject, nó có hai phương thức quan tâm, "setArg:" và "getArg" được thiết lập và nhận được một ivar float. Đây là một ví dụ nhỏ ngớ ngẩn, nhưng nó cho thấy cách sử dụng nó. Dưới đây là một file prefix tôi đã viết cho LLĐB:

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

trong tập tin ~/.lldbinit tôi thêm

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

và bây giờ tôi có thể làm

(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 

Bạn sẽ nhận thấy tôi bao gồm một vài chức năng thư viện C chuẩn ở đây. Sau khi thực hiện việc này, tôi không cần phải truyền các loại trả lại này nữa, ví dụ:

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

(. Bản vá cho rằng "< không có kết quả >" điều đã cam kết các nguồn LLĐB TOT đã)

+0

expr - [self setAlpha: 0.5f] hoặc expr - [self setAlpha: 1] cả hai chế độ xem được đề cập hoàn toàn biến mất khỏi màn hình. Có vẻ như có điều gì đó đang xảy ra, nhưng chắc chắn không phải là điều đúng đắn. Tôi chỉ có thể gõ các lệnh này khi tôi đặt điểm ngắt. Hoặc là có một cách để làm những việc như thế này trong khi mã vẫn đang chạy/bỏ tạm dừng? –

+0

Không, bạn cần quá trình dừng lại khi bạn gọi phương thức này. Nếu bộ chọn này có một kiểu float, có một thiếu sót bạn có thể gặp với lldb của Xcode 4.5 - nếu đối số hàm nhận một kiểu float và bạn không có thông tin gỡ rối, lldb không cung cấp cho bạn bất kỳ cách nào để chuyển giá trị dưới dạng phao. Nó sẽ vượt qua nó như là một điều kiện vô điều kiện kép, tuân theo các quy tắc khuyến mãi đối số không có nguyên mẫu của ngôn ngữ C cũ. Nếu lldb có thông tin gỡ lỗi cho lớp này, nó sẽ có thể làm điều đúng. Nhiều trường hợp của vấn đề này trong lập trình ObjC sẽ được sửa trong một bản phát hành trong tương lai. –

+0

NB: Nếu bạn gặp vấn đề tôi muốn nói với float v. Double, giá trị bạn chuyển vào setAlpha của bạn sẽ không phải là những gì bạn mong đợi, nó sẽ là số ngẫu nhiên có thể rất gần 0, ví dụ. –

2

Nếu bạn cần nhiều dòng, sử dụng expression:

expression 

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

// code will execute now 

Trống dòng để hoàn thành và thực thi mã.

Các vấn đề liên quan