2010-10-28 35 views
30

Thời gian chạy của Objective-C có vẻ khá mạnh mẽ, vì vậy tôi đã tự hỏi liệu có cách nào để ghi tên hàm được gọi là hàm hiện tại (cho mục đích gỡ lỗi) hay không.In tên hàm gọi tới nhật ký gỡ lỗi

Tình huống của tôi là một loạt các thứ được gán cho một thuộc tính và thay vì đặt điểm ngắt và kiểm tra ngăn xếp cuộc gọi mỗi lần, tôi chỉ muốn NSLog tên của chức năng đang đặt thuộc tính, cùng với giá trị mới.

Vì vậy, bạn có thể truy cập vào ngăn xếp cuộc gọi khi chạy?

Trả lời

42

Hãy thử điều này:

#include <execinfo.h> 

void *addr[2]; 
int nframes = backtrace(addr, sizeof(addr)/sizeof(*addr)); 
if (nframes > 1) { 
    char **syms = backtrace_symbols(addr, nframes); 
    NSLog(@"%s: caller: %s", __func__, syms[1]); 
    free(syms); 
} else { 
    NSLog(@"%s: *** Failed to generate backtrace.", __func__); 
} 
+0

Điều này làm việc tuyệt vời nếu bạn thay thế 'sizeof (addr)' bằng 'sizeof (addr)/sizeof (void *)' (hoặc chỉ 2). Cảm ơn! – Brian

+14

Đã sửa lỗi. Oh, và Foundation thực sự phơi bày điều này thực sự đơn giản thông qua '- [NSThread callStackSymbols]', nó trả về một mảng. Bạn có thể sử dụng nó như là 'NSArray * syms = [[NSThread currentThread] callStackSymbols]; if ([syms count]> 1) NSLog (@ "người gọi:% @", [syms objectAtIndex: 1U]; ' –

+5

bình luận cuối cùng:' callStackSymbols' là một phương thức lớp. Bạn phải sử dụng nó như '[NSThread callStackSymbols]' – user102008

2

Không có cơ sở để nhận người gửi. Hoặc, ít nhất, không có gì là trung tâm với Objective-C.

Có một vài lựa chọn thay thế.

Trước tiên, bạn có thể sử dụng lệnh GDB. Chuyển đến bảng điều khiển GDB và thực hiện như sau:

comm 1 
bt 
po argName 
cont 

Hoặc, bạn có thể sử dụng dtrace. Điều này thật khó. Hoặc bạn có thể sử dụng các dụng cụ làm cho dtrace hơi dễ dàng hơn.

Hoặc bạn có thể sử dụng hàm backtrace(). Xem trang backtrace man (x-man-page: // backtrace).

0

Có macro C được gọi là __PRETTY_FUNCTION__ sẽ trả về C-String với tên của hàm hiện tại. Nếu bạn muốn chuyển đổi thành NSString để dễ dàng in sang NSLog, bạn có thể tạo macro với

#define NSSTRING_PRETTY_FUNCTION [NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSASCIIStringEncoding] 

Tôi luôn sử dụng nó trong các dự án của mình.

+4

Bạn không đọc câu hỏi đúng cách. Nó không phải là tên của chức năng hiện tại cần thiết, mà là người gọi. – JeremyP

30

Câu hỏi lớn. Kết hợp câu trả lời của Jeremy ở trên và những gì chúng tôi luôn sử dụng để gỡ lỗi, bạn sẽ nhận được một chuỗi tốt đẹp như sau:

NSArray *syms = [NSThread callStackSymbols]; 
if ([syms count] > 1) { 
    NSLog(@"<%@ %p> %@ - caller: %@ ", [self class], self, NSStringFromSelector(_cmd),[syms objectAtIndex:1]); 
} else { 
    NSLog(@"<%@ %p> %@", [self class], self, NSStringFromSelector(_cmd)); 
} 
+0

Cần gọi đoạn mã này ở đâu đó? – Shamsiddin

+0

Có, bạn cần gọi hàm này trong hàm tương ứng nơi bạn muốn đăng nhập – LordT

+0

Tôi đã làm như bạn đã nói, nhưng ông đã không in tất cả lịch sử ory của phương pháp làm việc bắt đầu từ chạy dự án. – Shamsiddin

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