CoreGraphics/MapKitのクラッシュをデバッグする

私のアプリケーションがiPhone上で動作しているときに断続的なクラッシュが発生しています。すべてのクラッシュは同じで、何らかの形でMKMapViewオーバーレイ(MKCircleViews)を伴います。

典型的なiPhone 4sのクラッシュレポートから:

レポートヘッダー:

Hardware Model:      iPhone4,1
Process:         EL-GPS-01 [1021]
Path: /var/mobile/Applications/61288E15-74B5-45B9-99A9-E0B58C767816/EL-GPS-01.app/EL-GPS-01
Identifier:      EL-GPS-01
Version:         ??? (???)
Code Type:       ARM (Native)
Parent Process:  launchd [1]

Date/Time:       2011-11-22 15:59:41.065 +0000
OS Version:      iPhone OS 5.0.1 (9A405)
Report Version:  104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000
Crashed Thread:  6

そしてクラッシュしたスレッド:

Thread 6 name: Dispatch queue: com.apple.root.default-priority
Thread 6 Crashed:
0 ??? 0000000000 0 + 0
1 CoreGraphics 0x319a87c2 0x31967000 + 268226
2 CoreGraphics 0x3199a9e6 0x31967000 + 211430
3 MapKit 0x37ec3564 0x37e6f000 + 345444
4 MapKit 0x37ec3652 0x37e6f000 + 345682
5 MapKit 0x37ecc0a4 0x37e6f000 + 381092
6 QuartzCore 0x3341be18 0x33410000 + 48664
7 QuartzCore 0x334d77e0 0x33410000 + 817120
8 QuartzCore 0x3346af24 0x33410000 + 372516
9 libdispatch.dylib 0x3797e892 0x3797b000 + 14482
10 libsystem_c.dylib 0x360e31ca 0x360d9000 + 41418
11 libsystem_c.dylib 0x360e30a0 0x360d9000 + 41120

私のiPhoneが私のラップトップに接続されている間にアプリケーションがクラッシュすると、出力パネルで次のように表示されます。

warning: check_safe_call: could not restore current frame
warning: Unable to restore previously selected frame.

デバッガでは何も表示されず、Issueナビゲータでスタックに何もないクラッシュされたスレッドが表示されます。

この問題をここで強調している非常に簡単なプロジェクトがあります:

https://github.com/1ndivisible/MKOverlayBug

[email protected]:1ndivisible/MKOverlayBug.git

私はこれにどのように接近するか分からない。ここに私が使用できる情報はありますか?クラッシュはフレームワークの深いところから発生しているようです。

10
私はシミュレータとデバイスの5.0で自分自身のアプリケーションでこのクラッシュを打っています。慰めがあれば、iOS 5.1で修正されているようだ。
追加された 著者 cbowns,
このリソースへのポイント以下のリンクアンサー。それは将来削除される可能性があるので、ここでこれを追加します。
追加された 著者 halfer,
シミュレータでうまくいきましたか?私にとっては、同じことでクラッシュすることはありません。しかし、はい、私はそれをつかむようにしようとすると...それはあなたが直面している問題ですか?
追加された 著者 Ajay Sharma,

4 答え

Its a known bug. Apple have acknowledged it. There is currently no fix. All you can do is compound your graphics into fewer annotations. I have found <=3 annotations is safe.

3
追加された
私はAppleにTSIを提出し、彼らは私にバグとしてそれを提出するように言いました。他の開発者も同じことをしました。彼は回避策があるかどうか尋ね、彼らは「今の時点ではありません。これはおそらく6週間前です。 Appleのパンくずリストの例を見て、あなたのグラフィックを3つ以下の注釈に組み合わせることをお勧めします。私はこのバグを打ち負かすために長い時間を費やしており、それは私が取る必要があった解決策でした。あなたが私にPMを送ってくれれば、あなたにいくつかのコードを送ってうれしいですが、それは実際にAppleのパンくずリストの例から得られたものです。
追加された 著者 Undistraction,
追加された 著者 Undistraction,
いいえ、私は決してそれを分離できませんでした。それは常にインタラクションやアニメーションによって引き起こされますが、いつも予測できませんでした。私は3つ以上のオーバーレイでバグが最終的に浮かび上がることに気付きました。シミュレートされた位置データを設定し、マップパニングをしばらく実行して中心の位置を維持してください。私はあなたがクラッシュが発生することがわかるでしょう。あなたの状況はどういうものですか?いつあなたはクラッシュを経験していますか?
追加された 著者 Undistraction,
@timthetoolmanこれは実際に私からの非常に古い投稿です。私の現在のコードは、ボトムアップから完全に書き直されています。それは、私ではなく、賞金を始めたもう1人のポスターです。私はバグを追跡しようとしていた時から彼を助け、彼を助けてくれることを望んで私の元の質問に続いて学んだことを結びつけているだけです。
追加された 著者 Undistraction,
これについての参考資料がありますか?
追加された 著者 Nikolai Ruhe,
バグの原因となる他の条件が分かっていますか?米国の50州ごとに25以上の注釈と個々のマップで問題がないからです。
追加された 著者 timthetoolman,
私はクラッシュしない。なぜ私はそれがクラッシュしていると思うか私の答えを参照してください。 githubに投稿したコードに基づいて、なぜクラッシュに問題があるのか​​を知ることができます。シミュレートされたルートでシミュレータを実行すると、自分のMacBook Proが疲れてしまいます。
追加された 著者 timthetoolman,

私はあなたの記憶がなくなっていると思うか、あなたはMapKitのバグに対して走っています。しかし、防御上、オーバーレイとMKビューを正しく使用しているようではなく、非常に多くの潜在的なオーバーレイを追跡してMKMapViewに負担をかけているようです。適例。次の方法で現在の場所に50のオーバーレイを追加しているとき:

-(void)addOverlays
{
    CLLocation *currentLocation = self.mapView.userLocation.location;

    for(int i = 0; i < 50; i++)
    {
       MKCircle *circle = [MKCircle circleWithCenterCoordinate:currentLocation.coordinate radius:50];
       [self.mapView addOverlay:circle];
    }
}

時間が経つと、MKMapViewが追跡しなければならない多数のオーバーレイと、同時に表示する必要のあるMKViewsを追加することができます。あなたのサンプルコードとiPhoneシミュレータの位置シミュレータで、MKMapViewの1800 MKCircleとMKCircleViewsに蓄積された簡単な自転車乗り継ぎルート。

心に留めておくべきことがいくつかあります:

  1. 場所ごとにあまり多くのオーバーレイを追加しないでください。 1で十分です。 50は過剰です。
  2. それぞれの場所には1つのMKCircleで十分です。わからない理由 あなたは、それぞれに多くのサークルを追跡して描画することを選択しています 場所。
  3. オーバーレイをMapViewに渡す方が効率的です。 マップの一部に必要なオーバーレイのみを与えます 表示します。 WWDC2011のビデオ「セッション111 - 可視化 MapKitを使用した地理的情報」を参照してください。 これまたはHazardMapのサンプルコードです。

あなたはこれらの行に沿って何かをすることができます:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
  {
   //Add it to an NSArray that you use to keep track of ALL the overlays
    [self.allOverlays addObject: MKCircle *circle = [MKCircle circleWithCenterCoordinate:currentLocation.coordinate radius:50]];

    //Now add it to the mapView if it is in the current region

    //code to check to see if currentLocation is within the current map region

     if (overlayIsInMapRegion){
         [mapView addOverlay: circle];
     } 
}

次に、領域が変わるたびに、MapViewがデリゲートメソッドを呼び出すときに必要なオーバーレイを計算します。

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

その領域をmapViewから取得し、その領域にあるオーバーレイの配列を作成します。次の行に沿った何か:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
   //Create a method that takes the region and calculates which overlays it contains
    NSArray *newOverlays=[self overlaysForRegion: mapView.region fromAllOverlays: self.allOverlays];
    if ([newOverlays count]>0){
         [mapView removeOverlays];
         [mapView addOverlays: newOverlays];
    }

}

お役に立てれば。がんばろう!

ティム

3
追加された

KERN_INVALID_ADDRESS(0x00000000クラッシュスレッド:6

これは、何かがヌルポインタを逆参照しようとしたことを伝えます。アノテーションを持たない場合は、おそらくアノテーション、またはアノテーションに属しているデータをリリースしたでしょう。ゾンビを有効にしてデバッガの下でアプリケーションを実行し、あなたが得るものを見てください。

また、静的アナライザーをプロジェクト全体に実行し、見つかった問題のすべてを修正します。

1
追加された
お返事をありがとうございます。スタティック・アナライザには問題はなく、計測器には漏れがありません。ゾンビを有効にすることは、クラッシュの前に、またはクラッシュの結果として、何も助けたり報告したりすることはありません。私は素人の骨にコードを取り除いたので(それはMKMapViewにオーバーレイを追加するだけです)、私はまだ同じ問題を抱えています。断続的なクラッシュは、10個のオーバーレイが追加された後に発生する可能性があります。または、200後に発生する可能性があります。
追加された 著者 Undistraction,
MapKitへの呼び出しがスレッド6ではなく、メインスレッドで起こっている理由を理解することから始めます。
追加された 著者 Mark Adams,

この場合、アドレス0(コードはそこからデータにアクセスするのではなく)でコードを実行しようとしている可能性があります。デバッガで再びクラッシュする場合は、PCレジスタの値を確認してください。値がゼロの場合、データをフェッチしないでゼロで実行しています。

この場合、実行中にスタックが破損している可能性があります。ローカル変数の一部のバッファオーバーフローによって、スタックフレームの戻りアドレスにゼロが入る可能性があります。

0
追加された