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.

Robottobor
sumber

Jawaban:

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

Kode ini berfungsi di utas apa pun.

smokris
sumber
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;
    }
}
Zayin Krige
sumber
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.

vt.
sumber
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]
Max Stewart
sumber
1
Perhatikan, meskipun ini hanya akan bekerja di dalam handler pengecualian terdaftar (tidak, misalnya, dalam blok @catch)
Barry Wark
2

Sebagai pengecualian, Anda dapat menggunakan anggota NSStackTraceKey dari kamus userInfo pengecualian untuk melakukan ini. Lihat Mengontrol Respons Program terhadap Pengecualian di situs web Apple.

Ben Gottlieb
sumber
Bagaimana cara menggunakan Swift?
Pedro Paulo Amorim
1

Di cetak cepat dengan cara ini:

print("stack trace:\(Thread.callStackSymbols)")
Deepak
sumber