Làm thế nào để bạn in ra một dấu vết ngăn xếp vào bảng điều khiển / đăng nhập trong ca cao?


293

Tôi muốn ghi lại dấu vết cuộc gọi trong một số điểm nhất định, như xác nhận thất bại hoặc ngoại lệ chưa được phát hiện.

Câu trả lời:


544
 NSLog(@"%@",[NSThread callStackSymbols]);

Mã này hoạt động trên bất kỳ chủ đề.


14
Tính năng mới trong Mac OS X 10.6, không tồn tại khi câu hỏi này ban đầu được hỏi. Đối với Pre-Snow-Leopard, sử dụng backtracevà các backtrace_symbolschức năng; xem trang chủ backtrace (3).
Peter Hosey

6
Chỉ có trên iOS 4.0 trở lên.
Danra

Cảm ơn! Có cách nào để làm điều này chỉ in dấu vết ngăn xếp, giả sử, giảm 6 cấp thay vì tất cả các cách?
sudo

9000, sử dụng backtrace/backtrace_symbolstrực tiếp
dymv 27/2/2015

34

Câu trả lời của n13 không thực sự hiệu quả - Tôi đã sửa đổi nó một chút để đưa ra điều này

#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        int retval;
        @try{
            retval = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
        @catch (NSException *exception)
        {
            NSLog(@"Gosh!!! %@", [exception callStackSymbols]);
            @throw;
        }
        return retval;
    }
}

4
Gah ... Apple nên biến điều này thành một tiêu chuẩn ít nhất là trong khi phát triển một ứng dụng. Một loạt các địa chỉ bộ nhớ là ... cổ xưa
Nga

Tôi đặt những cải tiến của bạn trong câu trả lời của tôi; Tôi đã làm điều này trước ARC. Cảm ơn.
n13

1
Điều này không hoạt động trong mọi tình huống. Đây là một cách tiếp cận tốt hơn nếu bạn muốn nắm bắt tất cả các ngoại lệ chưa được phát hiện: codereview.stackexchange.com/questions/56162/ mẹo (Mã trong câu hỏi đó hơi phức tạp một chút, nhưng nó cũng không chỉ đơn giản là ghi nhật ký các biểu tượng ngăn xếp cuộc gọi.)
nhgrif

Bạn có thể thêm NSLog(@"[Error] - %@ %@", exception.name, exception.reason);nếu bạn cũng muốn ngoại lệ thực tế
Corentin S.

9

Ca cao đã ghi lại dấu vết ngăn xếp trên các ngoại lệ chưa được lưu vào bảng điều khiển mặc dù chúng chỉ là địa chỉ bộ nhớ thô. Nếu bạn muốn thông tin tượng trưng trong bảng điều khiển, có một số mã mẫu từ Apple.

Nếu bạn muốn tạo theo dõi ngăn xếp tại một điểm tùy ý trong mã của bạn (và bạn đang ở trên Leopard), hãy xem trang man backtrace. Trước Leopard, bạn thực sự phải tự đào qua ngăn xếp cuộc gọi.


6
Rõ ràng có sẵn trong iOS 4 nhưng không phải 3.2. Đây là những gì tôi đã sử dụng, được sao chép một cách đáng xấu hổ từ trang man backtrace: #include <execinfo.h> ... void * callstack [128]; int i, frames = backtrace (callstack, 128); char ** strs = backtrace_symbols (callstack, frames); for (i = 0; i <frames; ++ i) {printf ("% s \ n", strs [i]); } miễn phí (strs);
mharper

Được gọi trong HandleException, nó ghi lại dấu vết của hàm xử lý, trong khi [NSException callStackSymbols] hiển thị ngăn xếp của nơi mà ngoại lệ đã đưa ra. Nhưng nếu bạn thay thế "backtrace (...)" bằng: "NSArray Array = [ex callStackReturnAddresses]; int frames = Array.count; for (i = 0; i <frames; ++ i) callstack [i] = ( void) [((NSNumber *) [Array objectAt Index: i]) intValue]; " bạn sẽ nhận được dấu vết ngăn xếp ngoại lệ hiện tại. Đây là cách [NSException callStackSymbols] hoạt động, tôi cho rằng: dấu vết họ trả lại bằng nhau và trong cả hai cuộc gọi ứng dụng được thay thế bằng _mh_execute_header khi phát hành.
Tertium

6

Điều này khá nhiều cho bạn biết phải làm gì.

Về cơ bản, bạn cần thiết lập xử lý ngoại lệ ứng dụng để ghi nhật ký, đại loại như:

#import <ExceptionHandling/NSExceptionHandler.h>

[[NSExceptionHandler defaultExceptionHandler] 
                  setExceptionHandlingMask: NSLogUncaughtExceptionMask | 
                                            NSLogUncaughtSystemExceptionMask | 
                                            NSLogUncaughtRuntimeErrorMask]

1
Lưu ý, mặc dù điều này sẽ chỉ hoạt động trong một trình xử lý ngoại lệ đã đăng ký (không, ví dụ: trong khối @catch)
Barry Wark


1

In nhanh chóng theo cách này:

print("stack trace:\(Thread.callStackSymbols)")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.