it-swarm-id.com

Debug Xcode 4.2 tidak melambangkan panggilan stack

Saya memiliki masalah dengan debugging Xcode 4.2 di simulator/perangkat iOS 5. Kode berikut macet, seperti yang diharapkan:

NSArray *arr=[NSArray array];
[arr objectAtIndex:100];

Di iOS 4, saya mendapatkan jejak tumpukan nomor hex yang bermanfaat. Tetapi di iOS 5, itu hanya memberi saya:

*** First throw call stack:
(0x16b4052 0x1845d0a 0x16a0674 0x294c 0x6f89d6 0x6f98a6 0x708743 0x7091f8 0x7fcaa9 0x2257fa9 0x16881c5 0x15ed022 0x15eb90a 0x15eadb4 0x15eaccb 0x6f02a7 0x6faa93 0x2889 0x2805)

Terima kasih.

140
cekisakurek

Tidak ada yang saya coba untuk memperbaikinya (mencoba kedua kompiler, kedua debugger, dll.) Setelah memutakhirkan XCode untuk pembaruan iOS 5, tampaknya tidak ada jejak tumpukan yang berfungsi.

Namun, saya telah menemukan solusi yang efektif - membuat penangan pengecualian saya sendiri (yang juga berguna untuk alasan lain). Pertama, buat fungsi yang akan menangani kesalahan dan output ke konsol (serta apa pun yang ingin Anda lakukan dengannya):

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"CRASH: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    // Internal error reporting
}

Selanjutnya, tambahkan penangan pengecualian ke delegasi aplikasi Anda:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{   
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    // Normal launch stuff
}

Itu dia!

Jika ini tidak berhasil, maka ada hanya dua alasan yang mungkin:

  1. Ada sesuatu yang menimpa panggilan NSSetUncaughtExceptionHandler Anda (hanya ada satu penangan untuk seluruh aplikasi Anda). Sebagai contoh, beberapa perpustakaan pihak ke-3 mengatur uncaughtExceptionHandler mereka sendiri. Jadi, cobalah mengaturnya di AKHIR fungsi didFinishLaunchingWithOptions Anda (atau menonaktifkan pustaka pihak ketiga secara selektif). Atau lebih baik lagi, tetapkan titik istirahat simbolis pada NSSetUncaughtExceptionHandler untuk dengan cepat melihat siapa yang memanggilnya. Yang mungkin ingin Anda lakukan adalah memodifikasi yang sekarang daripada menambahkan yang lain.
  2. Anda tidak benar-benar menemukan pengecualian (misalnya, EXC_BAD_ACCESS adalah tidak pengecualian; kredit untuk komentar @Erik B, di bawah)
255
Zane Claes

Ada opsi yang berguna untuk menambahkan Exception Breakpoint (menggunakan + di bagian bawah Breakpoint Navigator). Ini akan berhenti pada Pengecualian apa pun (atau Anda dapat mengatur kondisi). Saya tidak tahu apakah pilihan ini baru di 4.2 atau jika saya akhirnya menyadari bahwa ini mencoba menyelesaikan masalah simbol yang hilang.

Setelah Anda mencapai breakpoint ini Anda dapat menggunakan Debug Navigator untuk menavigasi tumpukan panggilan, memeriksa variabel, dll seperti biasa.

Jika Anda menginginkan tumpukan panggilan simbolis yang cocok untuk disalin/ditempelkan atau sejenisnya, gtrb backtrace akan berfungsi dengan baik dari sana:

(gdb) bt
#0  0x01f84cf0 in objc_exception_throw ()
#1  0x019efced in -[NSObject doesNotRecognizeSelector:] ()

(dll)

109
WiseOldDuck

Ada fitur baru pada debugger. Anda dapat mengatur break point kapan saja pengecualian dilemparkan dan menghentikan eksekusi di sana, seperti yang biasanya terjadi pada 4.0.

Pada "Breakpoint Navigator", tambahkan "Exception Breakpoint" dan cukup tekan "Done" pada popup opsi.

Itu saja!

PS: Dalam beberapa kasus akan lebih baik untuk istirahat hanya untuk pengecualian Objective-C.

46
Pedro

Ini adalah satu solusi lagi, tidak seanggun sebelumnya, tetapi jika Anda tidak menambahkan breakpoint atau handler pengecualian, itu bisa menjadi satu-satunya cara.
Saat aplikasi mogok, dan Anda mendapatkan tumpukan panggilan baku pertama Anda (dalam angka hex), ketikkan ke konsol Xcode info line *hex (jangan lupa beri bintang dan 0x hex specifier), misalnya:

(gdb) info line *0x2658
Line 15 of "path/to/file/main.m" starts at address 0x25f2 <main+50>
and ends at 0x267e <main+190>.

Jika Anda menggunakan lldb, Anda dapat mengetik image lookup -a hex (Tanpa bintang dalam situasi ini), dan Anda mendapatkan hasil yang serupa.

Dengan metode ini, Anda dapat melintasi dari atas tumpukan lemparan (akan ada sekitar 5-7 penyebar pengecualian sistem) ke fungsi Anda yang menyebabkan kerusakan, dan menentukan file dan baris kode yang tepat.

Juga, untuk efek serupa Anda dapat menggunakan utilitas Atos di terminal, cukup ketik:

atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ...

dan Anda mendapatkan jejak stack yang dilambangkan (setidaknya untuk fungsi Anda memiliki simbol debug). Metode ini lebih disukai, karena Anda tidak memiliki untuk setiap panggilan alamat info line, Cukup salin alamat dari output konsol dan tempelkan ke terminal.

21
Alexander

Anda dapat menambahkan Pengecualian Breakpoint (menggunakan + di bagian bawah Breakpoint Navigator) dan menambahkan tindakanbt untuk itu (klik tombol Tambah Aksi , pilih Perintah Debugger, masukkan "bt" di bidang teks). Ini akan menampilkan jejak tumpukan segera setelah pengecualian dilemparkan.

9
MonsieurDart

Pada konsol debug Xcode, ketik Prompt:

image lookup -a 0x1234

Dan itu akan menunjukkan kepada Anda sesuatu seperti:

  Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088)
  Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202
6
Matt Connolly

Ini adalah masalah umum, tidak mendapatkan jejak stack di 4.2. Anda dapat mencoba bertukar antara LLDB dan GDB untuk melihat apakah Anda mendapatkan hasil yang lebih baik.

Ajukan laporan bug di sini.

http://developer.Apple.com/bugreporter/

EDIT:

Saya percaya bahwa jika Anda menukar kembali ke LLVM GCC 4.2 Anda tidak akan melihat ini terjadi. Anda mungkin kehilangan fitur yang Anda butuhkan.

6
logancautrell

Gunakan kode ini di fungsi utama Anda:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    int retVal;
    @try {
        retVal = UIApplicationMain(argc, argv, nil, nil);
    }
    @catch (NSException *exception) {
        NSLog(@"CRASH: %@", exception);
        NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    }
    @finally {
        [pool release];
    }
    return retVal;
}
6
wilson lin

Mengaktifkan 'Kompilasi untuk Ibu Jari' (konfigurasi debug) berhasil untuk saya.

1
Bradweiser86