Bagaimana Anda mencetak jejak tumpukan ke konsol / log in Kakao?


293

Saya ingin mencatat jejak panggilan selama titik-titik tertentu, seperti pernyataan yang gagal, atau pengecualian yang tidak tertangkap.

Jawaban:


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

Kode ini berfungsi di utas apa pun.


14
Baru di Mac OS X 10.6, yang tidak ada saat pertanyaan ini awalnya diajukan. Untuk pra-Snow-Leopard, gunakan backtracedan backtrace_symbolsfungsinya; lihat manual backtrace (3).
Peter Hosey

6
Hanya di iOS 4.0 dan di atasnya.
Danra

Terima kasih! Apakah ada cara untuk membuat ini hanya mencetak jejak tumpukan, katakanlah, 6 level ke bawah daripada semua jalan?
sudo

9000, gunakan backtrace/backtrace_symbolslangsung
dymv

34

Jawaban n13 tidak cukup bekerja - saya memodifikasinya sedikit untuk menghasilkan ini

#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 harus menjadikan ini standar setidaknya saat mengembangkan aplikasi. Banyak alamat memori ... archaic
Russ

Saya menempatkan perbaikan Anda dalam jawaban saya; Saya melakukan ini sebelum ARC. Terima kasih.
n13

1
Ini tidak berfungsi dalam semua situasi. Ini adalah pendekatan yang lebih baik jika Anda ingin menangkap semua pengecualian yang tidak tertangkap: codereview.stackexchange.com/questions/56162/… (Kode dalam pertanyaan itu sedikit rumit, tetapi juga lebih dari sekadar mencatat simbol tumpukan panggilan.)
nhgrif

Anda dapat menambahkan NSLog(@"[Error] - %@ %@", exception.name, exception.reason);jika Anda menginginkan pengecualian yang sebenarnya juga
Corentin S.

9

Kakao sudah mencatat jejak tumpukan pada pengecualian tanpa tertangkap ke konsol meskipun mereka hanya alamat memori mentah. Jika Anda ingin informasi simbolik di konsol ada beberapa kode contoh dari Apple.

Jika Anda ingin membuat jejak stack pada titik sembarang dalam kode Anda (dan Anda menggunakan Leopard), lihat halaman manual backtrace. Sebelum Leopard, Anda sebenarnya harus menggali melalui tumpukan panggilan itu sendiri.


6
Tampaknya tersedia di iOS 4 tetapi tidak 3.2. Inilah yang saya gunakan, tanpa malu-malu disalin dari halaman manual backtrace: #include <execinfo.h> ... void * callstack [128]; int i, frames = backtrace (callstack, 128); char ** strs = backtrace_symbols (callstack, frames); untuk (i = 0; i <frames; ++ i) {printf ("% s \ n", strs [i]); } gratis (strs);
mharper

Dipanggil di HandleException ia menulis jejak fungsi handler itu sendiri, sementara [NSException callStackSymbols] menunjukkan tumpukan tempat di mana pengecualian telah meningkat. Tetapi jika Anda mengganti "backtrace (...)" dengan: "NSArray arr = [ex callStackReturnAddresses]; int frames = arr.count; untuk (i = 0; i <bingkai; ++ i) callstack [i] = ( void) [((NSNumber *) [arr objectAtIndex: i]) intValue]; " Anda akan mendapatkan jejak stack pengecualian saat ini. Beginilah cara [NSException callStackSymbols] bekerja, saya kira: jejak yang mereka kembalikan sama dan di kedua panggilan aplikasi digantikan oleh _mh_execute_header dalam rilis.
Tertium

6

Ini cukup banyak memberi tahu Anda apa yang harus dilakukan.

Pada dasarnya Anda perlu mengatur pengecualian aplikasi yang menangani untuk log, sesuatu seperti:

#import <ExceptionHandling/NSExceptionHandler.h>

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

1
Perhatikan, meskipun ini hanya akan bekerja di dalam handler pengecualian terdaftar (tidak, misalnya, dalam blok @catch)
Barry Wark


1

Di cetak cepat dengan cara ini:

print("stack trace:\(Thread.callStackSymbols)")
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.