Cocoaのコンソール/ログにスタックトレースをどのように出力しますか?


293

アサーションの失敗やキャッチされない例外など、特定の時点でのコールトレースをログに記録したい。

回答:


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

このコードはどのスレッドでも機能します。


14
Mac OS X 10.6の新機能です。この質問が最初に行われたときには存在しませんでした。Snow-Leopard以前の場合は、backtraceおよびbacktrace_symbols関数を使用します。backtrace(3)のマンページを参照してください。
Peter Hosey、2010

6
iOS 4.0以降のみ。
Danra

ありがとう!これをスタックトレースだけを印刷する方法はありますか?たとえば、すべての方法ではなく6レベル下に印刷しますか?
sudo 14

9000、backtrace/backtrace_symbols直接使用
dymv 2015

34

n13の答えはうまくいきませんでした-これを思いつくように少し修正しました

#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は、少なくともアプリケーションを開発している間、これを標準にする必要があります。メモリアドレスの束は...古風な
Russ

私はあなたの改善を私の答えに入れました。私はこれをARCの前に行いました。ありがとう。
n13 2014

1
これすべての状況で機能するわけではありません。あなたはすべてキャッチされない例外をキャッチしたい場合、これは、より良いアプローチです:codereview.stackexchange.com/questions/56162/...(その問題のコードはovercomplicated少しですが、それは、単にコールスタックの記号をログ以上ありません。)
nhgrif 14

NSLog(@"[Error] - %@ %@", exception.name, exception.reason);実際の例外も必要な場合は追加できます
Corentin S.

9

Cocoaは、キャッチされていない例外のスタックトレースをすでにコンソールに記録していますが、それらは単なる生のメモリアドレスです。コンソールにシンボリック情報が必要な場合は、Appleのサンプルコードがいくつかあります

コードの任意のポイントでスタックトレースを生成する場合(そしてLeopardを使用している場合)は、backtraceのマニュアルページを参照してください。Leopardの前は、実際にはコールスタック自体を掘り下げる必要がありました。


6
どうやらiOS 4では利用可能だが3.2では利用できない。これが私が使用したもので、バックトレースのmanページから恥知らずにコピーされたものです。#include <execinfo.h> ... void * callstack [128]; int i、frames = backtrace(callstack、128); char ** strs = backtrace_symbols(callstack、frames); for(i = 0; i <フレーム; ++ i){printf( "%s \ n"、strs [i]); } free(strs);
mharper 2010

[NSException callStackSymbols]が例外が発生した場所のスタックを表示しながら、HandleExceptionで呼び出されると、ハンドラー関数自体のトレースを書き戻します。ただし、「backtrace(...)」を「NSArray arr = [ex callStackReturnAddresses]; int frames = arr.count; for(i = 0; i <frames; ++ i)callstack [i] =( void)[((NSNumber *)[arr objectAtIndex:i])intValue]; " 現在の例外スタックトレースを取得します。これが[NSException callStackSymbols]のしくみです。これらが返すトレースは等しく、両方のアプリの呼び出しで、リリースでは_mh_execute_headerに置き換えられています。
Tertium 2012

6

これはほとんど何をすべきかを教えてくれます。

基本的に、アプリケーションの例外処理をログに記録するように設定する必要があります。

#import <ExceptionHandling/NSExceptionHandler.h>

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

1
ただし、これは登録済みの例外ハンドラ内でのみ機能します(たとえば、@ catchブロックでは機能しません)
Barry Wark


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.