Xcode 4.2 hata ayıklama, yığın çağrısını göstermiyor


140

Bir iOS 5 simülatöründe / cihazında Xcode 4.2 hata ayıklama ile ilgili bir sorunum var. Aşağıdaki kod beklendiği gibi kilitleniyor:

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

İOS 4'te, onaltılık sayıların yararlı bir yığın izini alıyorum. Ancak iOS 5'te bana sadece şunları veriyor:

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

Teşekkürler.

Yanıtlar:


256

Denediğim hiçbir şey bunu düzeltemez (her iki derleyiciyi de, her iki hata ayıklayıcıyı da dener) iOS 5 güncellemesi için XCode'u yükselttikten sonra, yığın izleri işe yaramadı.

Ancak, etkili bir çözüm buldum - kendi istisna işleyicimi oluşturdum (diğer nedenlerle de yararlıdır). İlk olarak, hatayı işleyecek ve konsola çıktı verecek bir işlev oluşturun (bununla birlikte yapmak istediğiniz başka şeylerin yanı sıra):

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

Ardından, uygulama temsilcinize istisna işleyicisini ekleyin:

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

Bu kadar!

Bu işe yaramazsa, sadece iki olası neden vardır :

  1. NSSetUncaughtExceptionHandlerAramanızın üzerine bir şey yazılıyor (tüm uygulamanız için yalnızca bir işleyici olabilir). Örneğin, bazı 3. taraf kütüphaneler kendi uncaughtExceptionHandler öğelerini ayarlar. Bu nedenle, didFinishLaunchingWithOptionsişlevinizin SONUNDA ayarlamayı deneyin (veya 3. taraf kitaplıklarını seçerek devre dışı bırakın ). Ya da daha iyisi, NSSetUncaughtExceptionHandlerkimin aradığını hızlıca görmek için sembolik bir kırılma noktası ayarlayın . Yapmak isteyebileceğiniz şey, başka bir tane eklemek yerine mevcut olanınızı değiştirmek.
  2. Aslında (örneğin, bir istisna karşılaşmak değiliz EXC_BAD_ACCESSolduğunu değil bir istisna; kredi @Erik B'nin yorumlarına, aşağıda)

1
Bunu duyduğuma sevindim :) Bir dosyaya çökme günlüğünü yazmak ve kullanıcıdan bir sonraki açılışta göndermesini istemek için yararlı buluyorum (sadece sürüm modunda, hata ayıklama yoluna girmemek için). Bu, harika hata raporları almamı sağlıyor ... ve kullanıcılar sorunlarının ele alındığını biliyorlar :)
Zane Claes

2
Bu işe yaramaz gibi görünüyor - uncaughtExceptionHandlerrutin asla çağrılmıyor.
Hot Licks

1
Lütfen nasıl kullanılacağına daha açık olabilir misiniz? Benim için işe yaramıyor gibi görünüyor.
Danut Pralea

1
Oldukça üzgün xCode bunu bizim için göstermiyor.
Authman Apatira

1
Çok takdir! Apple'ın bu tür temel işlevleri IDE'ye uygulamaması şaşırtıcı.
devios1

110

İstisna Kesme Noktası ekleme konusunda yararlı bir seçenek vardır (Kesme Noktası Gezgini'nin altındaki + işaretini kullanarak). Bu, herhangi bir İstisna durumunda kesilecektir (ya da koşulları ayarlayabilirsiniz). Bu seçeneğin 4.2'de yeni olup olmadığını veya nihayetinde eksik semboller sorununu çözmeye çalışırken fark ettim mi bilmiyorum.

Bu kesme noktasına ulaştığınızda, çağrı yığınında gezinmek, değişkenleri vb. Her zamanki gibi incelemek için Hata Ayıklama Gezgini'ni kullanabilirsiniz.

Kopyalama / yapıştırma veya benzerlerine uygun sembolik bir çağrı yığını istiyorsanız, gdb backtrace oradan iyi çalışır:

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

(vb)


3
Bu benim için şimdiye kadar mükemmel çalışıyor. Hata ayıklayıcı çökme çizgisinde durur, geri izlemeye gerek yoktur.
Tim

1
Bu benim için de mükemmel. Çok teşekkür ederim, bu kırılma noktası olmadan
deliriyordum

+1 çalıştı. İstisnanın nedenini açıklayan çok güzel bir hata mesajı vermiyor, ancak bir başlangıç ​​...
Nicu Surdu

sen benim HotD @WiseOldDuck'sın.
Maverick1st

Bu benim için beklenen davranışı geri getiriyor. NOT: Ayrıca bu kesme noktasını yeni projelere tekrar eklemeyi unutmayın!
MechEthan

46

Hata ayıklayıcıda yeni bir özellik var. Bir istisna atıldığında bir kırılma noktası ayarlayabilir ve yürütme işlemini tıpkı 4.0'da olduğu gibi orada durdurabilirsiniz.

"Kesme Noktası Gezgini" üzerinde, bir "İstisna Kesme Noktası" ekleyin ve seçenekler açılır penceresinde "Bitti" ye basın.

Bu kadar!

Not: Bazı durumlarda yalnızca Objective-C istisnaları ihlal etmek daha iyi olur.


Kesinlikle bu benim için bir çözüm.
bradgonesurfing

Benim için sorun buydu. Bir meslektaşım ve ben aynı Xcode projesini paylaşıyoruz ve ona sorunun olup olmadığını sordum ve değildi. Aradaki fark, projesinin objektif c istisnalarını kırmasıydı (objc_exception_throw)
at

İzlenemeyen bir hata bulmaya yardım ettiniz. Çok teşekkür ederim. Bunun gibi birşey için her yere bakıyordum.
rjgonzo

1
Bu bir cazibe gibi çalışıyor! Tam da aradığım şey buydu, bu İstisna İşleyiciyi eklemekten daha iyidir çünkü Kesme Noktası eklenmesi sizi istisnanın atıldığı yere götürebilir, istisna işleyici çalışır, ancak sadece bir fikir verir.
im8bit

21

İşte bir öncekinden daha zarif olmayan bir çözüm daha, ancak istisna kesme noktaları veya işleyicileri eklemediyseniz, gitmek için sadece bir yol olabilir.
Uygulama çöktüğünde ve ham ilk çağrı çağrı yığınınızı (onaltılık sayılarla) aldığınızda , Xcode konsoluna yazın info line *hex(yıldız ve 0xonaltılı belirteci unutmayın ), örneğin:

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

Eğer lldb kullanıyorsanız , yazabilirsiniz image lookup -a hex(bu durumda yıldız olmadan) ve benzer çıktı elde edersiniz.

Bu yöntemle, atma yığınının üstünden (yaklaşık 5-7 sistem istisna propagandası olacak) bir çökmeye neden olan işlevinize geçebilir ve tam dosya ve kod satırını belirleyebilirsiniz.

Ayrıca, benzer etki için terminalde atos yardımcı programını kullanabilirsiniz, sadece şunu yazın:

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

ve sembolik yığın izlemesi elde edersiniz (en azından hata ayıklama sembolleriniz olan işlevler için). Bu yöntem daha çok tercih edilir, çünkü her adres çağrısı için sahip değilseniz info line, adresleri konsol çıkışından kopyalayın ve terminale yapıştırın.


9

İstisna Kesme Noktası ekleyebilir (Kesme Noktası Gezgini'nin altındaki + işaretini kullanarak) ve eylemi bt buna ekleyebilirsiniz (Eylem Ekle düğmesini tıklayın, Hata Ayıklayıcı Komutu'nu seçin, metin alanına "bt" girin). Bu, bir istisna atıldığında yığın izlemesini görüntüler.


6

Bu yaygın bir sorundur, 4.2'de yığın izleri almamak. Daha iyi sonuçlar alıp almadığınızı görmek için LLDB ve GDB arasında geçiş yapmayı deneyebilirsiniz.

Buraya bir hata raporu gönderin.

http://developer.apple.com/bugreporter/

DÜZENLE:

LLVM GCC 4.2 ile değiştirirseniz bunun gerçekleşmeyeceğini düşünüyorum. Gereksinim duyduğunuz özellikleri kaybedebilirsiniz.


evet derleyicileri değiştirmeyi denedim, ancak sorun devam ediyor. ama teşekkürler yine de :)
cekisakurek

Derleyicileri değil, hata ayıklayıcıları değiştirmeyi önerdi.
bames53

1
Bilginize: Bu örnekte, kullandığınız derleyicinin veya hata ayıklayıcının sürümü ile ilgisi yoktur. Bu, iOS'tan konsol çıkışındaki bir değişikliktir.
clarkcox3

Bunun ne kadar deneyimin değiştiği ilginç - bence birkaç sorun var. Hata ayıklayıcıyı istisna kesme noktasında durduramadım. GDB'den LLDB'ye geçmek sorunu çözdü.
Matt

6

Bu kodu ana işlevinizde kullanın:

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;
}

Bu, film şeritleriyle çalışmıyor gibi görünüyor. 2012-06-04 20: 34: 52.211 Sorunlar [1944: 207] Uygulama temsilcisi, ana film şeridi dosyasını kullanmak istiyorsa window özelliğini uygulamalıdır. 2012-06-04 20: 34: 52.213 Sorunlar [1944: 207] Uygulamaların, uygulama başlatıldığında bir kök görünüm denetleyicisine sahip olması bekleniyor
macasas

6

Xcode hata ayıklama konsolu istemine şunu yazın:

image lookup -a 0x1234

Ve size şöyle bir şey gösterecek:

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

Teşekkürler, gerçekten bunu arıyordum. Şaşırtıcı bir çağrı yığını olarak tüm "ilk atış çağrı yığını" görüntülemek için bir kısayol yok, sanırım bir Python lldb komut dosyası kolayca yazılabilir.
Ilya

1

'Başparmak için Derle'yi tekrar açmak (hata ayıklama yapılandırması) benim için çalıştı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.