mallocの「ダブルフリー」エラーの原因を見つける方法は?


80

Objective-Cでアプリケーションをプログラミングしていますが、次のエラーが発生します。

MyApp(2121,0xb0185000)malloc:***オブジェクト0x1068310のエラー:ダブルフリー
***デバッグするmalloc_error_breakにブレークポイントを設定します

NSAutoreleasePoolをリリースしたときに発生していて、2回リリースしているオブジェクトがわかりません。

彼のブレークポイントを設定するにはどうすればよいですか?

この「オブジェクト0x1068310」が何であるかを知る方法はありますか?


3
この投稿にiPhoneのタグを付けて、さらに多くの人を獲得することもできます
Benny Wong

4
「iphone」タグを削除して、他のより適切なタグを優先しました。
クインテイラー

3
このiPhoneの質問にiPhoneタグがない理由は想像できません。「自動リリース」のような他のタグよりも「iPhone」をフォローしている人の方が多いはずです。「自動解放」を見つけたい場合は、それを検索します。タグをたどりません。「iPhone」のバックを入れて、私はそう。
Nosredna

6
「iphone」タグを削除した理由は、質問についてiPhoneに固有のものが何もないためです。唯一のリンクは、iPhoneアプリで発生することですが、CまたはObjective-Cアプリケーションでもまったく同じエラーが発生する可能性があります。iPhoneをフォローしている人がさりげなくこれに興味を持ってくれるとは思いません。むしろ、「double free」や「malloc_error_break」などを検索する人で、「iPhone」を投げても表示されます。 。タグについては口論しないでください。ただし、回答する人は、質問がどこに最も適しているかを知っている可能性があることを考慮してください。
クインテイラー

3
この質問は、少なくともココア固有のものです。iPhoneタグが不快な場合は、カカオタグはどうですか?明らかな意図は、XCodeのCocoa上のObjective-Cに適用されます。Windows、Linux、またはXCodeのコンテキスト外ではObjective-Cではありません。
runako 2009年

回答:


38

デバッガーに割り込むと、オブジェクトが何であるかがわかります。コールスタックを調べるだけで、どこで解放できるかがわかります。それはそれがどのオブジェクトであるかを教えてくれます。

ブレークポイントを設定する最も簡単な方法は次のとおりです。

  1. ランに行く- >表示- >ブレークポイント(ALT- - )CommandB
  2. リストの一番下までスクロールして、記号を追加します malloc_error_break

1
私はそれを試しましたが、次のようになります:malloc_error_breakをディスアンブルできません....それはどういう意味ですか?
gonso 2009年

3
自動リリースのダブルフリーのヘルプはありません。彼はゾンビが必要です
Rog

58
@gonso —好奇心が強いのですが、これがうまくいかなかったのに、なぜそれを答えとして受け入れたのですか?
クインテイラー

8
Xcode 4.3.2では、ブレークポイントは[表示]→[ナビゲーター]→[ブレークポイントナビゲーターの表示]または⌘6(Cmd-6)
Andreas Ley

46

オブジェクトが「ダブルフリー」の場合、最も一般的な原因は、自動解放されたオブジェクトを(不必要に)解放していることです。後で、含まれている自動解放プールが空になると、オブジェクトは自動解放されます。

追加のリリースを追跡する最良の方法は、Xcodeで影響を受ける実行可能ファイルにNSZombieEnabled環境変数を使用することであることがわかりました。使用方法の概要については、このCocoaDevwikiページを確認してください。(このページに加えて、AppleはXcodeでコードをデバッグするための信じられないほどあいまいでありながら役立つヒントをいくつか文書化しており、そのうちのいくつかは私のベーコンを数回以上節約しました。developer.apple.comのこのテクニカルノートをチェックすることをお勧めします—リンクCocoaのFoundationフレームワークのセクションにジャンプします)。

編集: Xcodeデバッガー内で問題のあるオブジェクトを追跡できることがよくありますが、Instrumentsを使用して支援する方がはるかに簡単です。Xcodeから、「実行」→「パフォーマンスツールで開始」→「オブジェクトの割り当て」を選択すると、問題のあるオブジェクトを作成された場所までさかのぼることができます。(これは、上記のようにゾンビを有効にしている場合に最適に機能します。)注: Snow Leopardは、[実行]メニューからもアクセスできるゾンビツールをインストゥルメントに追加します。29ドルだけの価値があるかもしれません!;-)

あり、ここで、関連のSOの質問が


1
回答にリンクされているCocoaDevwikiページは死んでいます:(
Devarshi 2017


12

クイン・テイラーの答えに加えて、私の経験を追加したいだけです。

私のアプリの1つでは、データを解析してコアデータオブジェクトに保存し、後でこれらのオブジェクトをビューに表示する必要があります。実際、アプリは問題なく動作し、まったくクラッシュしません。何度も前後にナビゲートするストレステストを実行し、できるだけ速く複数のビューを開こうとするまでは。上記のメッセージでアプリがクラッシュします。

クインが彼の答えで提案したすべての方法を試しましたが、それでも正確な原因がどこにあるのかを見つけることができませんでした。

NSZombieEnabled = YESとNSStackLogging = YESを設定し、コマンドシェルmalloc_historyを実行して理由を調べましたが、それでもうまくいきませんでした。データをコアデータオブジェクトのどこに保存するかを常に示しています。実際、そこでリリースされたオブジェクトを1000回チェックしましたが、奇妙なことは何もありません。

さまざまなツール(割り当て、リークなど)を使用してInstrumentsで実行しても、まだ役に立ちませんでした。GuardMallocを有効にしても何も得られません。

最終的な救済:オブジェクトがCore Dataから取得され、これらすべてのオブジェクトに保持メッセージを送信したビューに戻ろうとし、これらの変更に注意しました。問題は解決しました!!!

それで、私はそれを保持できなかったことがわかりました、それがまさに原因です。私の経験を共有したいので、あなたはあなたのアプリのために別の救助を持っています。


9

Cmd + Shift + Rを押して、デバッガコンソールを開きます。そこに、タイプ

break malloc_error_break

の先頭にブレークポイントを設定するには malloc_error_break関数。

アドレス0x1068310にあるオブジェクトを確認する場合は、デバッガコンソールに次のように入力できます。

print-object 0x1068310

もちろん、オブジェクトがまだ生きている間にこれを行う必要があります。これを行うまでにオブジェクトがすでに解放されている場合、これは機能しません。


これは自動リリースです、彼はゾンビが必要です。
Rog

1
最後に私がしたことは、AutoreleasePollの外部で「疑わしい」メソッドを呼び出すことでした。おかしなことに、私はまだ警告を受けましたが、ブレークポイントはヒットしませんでした。行が見つかるまでブロックをコメントアウトしました。stringWithFormatで作成された文字列を自動解放していました(割り当てやコピーはありません)。ヒントありがとうございます!Gonso
gonso

この特定のタイプのバグの場合、malloc_error_breakでブレークしても問題を見つけるのに役立ちませんでした。常に、ゾンビを有効にする必要がありました。
クインテイラー

:XCodeの4にmalloc_error_breakのためのブレークポイントの設定方法については、こちらを参照してくださいstackoverflow.com/questions/6969407/...
benvolioT

1
@Zammbi:poエイリアスまたは同等のものを使用してみてくださいexpr -o。この回答が最初に作成されてから数年で、Xcodeで使用されるデバッグエンジンがGDBからLLDBに変更され、LLDBには異なるコマンドセットがあります。
アダムローゼンフィールド2015

4

私にとって、問題はによって解決されました

(gdb) call (void)_CFAutoreleasePoolPrintPools()

クラッシュ直後。スタックの一番上のアドレスは、犯人のアドレスでした。と出来上がりを投げたretain

ログメッセージに記載されているアドレスでは、どこにもアクセスできませんでした。さまざまなインストルメットのいずれにも表示されませんでした。どうやら、すでに解放されたいくつかの内部データへのポインタ。


4

Xcode4にシンボリックブレークポイントを追加する

これをXcode4に関連させるための単なる更新...

Xcodeの4ユーザーガイド

シンボリックブレークポイントを追加します。。。

  1. ブレークポイントナビゲーターの左下隅にある[追加]ボタンをクリックします。
  2. Add SymbolicBreakpointを選択します。
  3. [シンボル]フィールドにシンボル名を入力します。
  4. [完了]をクリックします。


2

クラスを確認し、deallocメソッドを確認してください。必ず電話してください[super dealloc].

私はこれとまったく同じ問題を抱えていて、[self dealloc]代わりに電話をかけていることがわかりました。ただ注意を払っていません。


2

無料のオブジェクトを見つけてアプリケーションをクラッシュさせる方法については、以下の手順をご覧ください。

1)「ブレークポイントナビゲーター」をクリックします。
2)次に、下にある「+」ボタンをクリックします。
3)リストから「SymbolicBreakpoint ...」を追加します。
4)「シンボル」オプションに「malloc_error_break」キーワードを追加します。

または、以下のGIFプレゼンテーションを参照することもできます。

GIF表現


1

これは通常、サファリやサファリプレビューなどの検査官によって引き起こされます。投稿または投稿質問を参照してください

AutoMatically Show Web ....の選択を削除すると、この問題が削除されます。

サファリまたはサファリプレビューを閉じるだけでは、この問題は解決されないことに注意してください。そして、サファリとサファリプレビューの両方の選択を解除する必要があります。

これでうまくいかない場合は、この回答を参照するか、投稿してデバッグしてください。

選択を解除すると、Safariプレビューで自動的に検査されます


0

Xcodeで、行番号の左側をクリックしてブレークポイントを設定します。次に、「ビルドとデバッグ」を実行して起動できます。

autoreleaseメモリはiPhoneの商品であるため、作成するオブジェクトを持たないことをお勧めします。Appleは明示的にを呼び出すことをお勧めしreleaseます。


0

これらの種類のメモリとポインタの問題を一般的に見つけるには、Valgrindのようなランタイムメモリエラーチェッカーに対してコードを実行する必要があります。これにより、コードがクラッシュする原因以外にも、コードが間違っている多くのことを指摘できるはずです。

ValgrindはOSXで動作することができ(「サポートされておらず、不完全でバグがある」と言われていますが)、少しハッキングするだけで、誰かがiPhoneSDK実行可能ファイルで動作するようになりました。

さらに良いことに、XCodeの一部であるInstrumentsを試すことができます。ここにそれを実行するためのチュートリアルがあります


1
楽器は行く方法です。オブジェクト割り当てインスツルメントを使用して、ゾンビをオンにします。(または単にゾンビーズテンプレートを使用します)。Valgrindは最後の手段の解決策です。それはひどく遅く、しばしば単に機能しません。
bbum 2009年

0

場合 malloc_error_breakない...

このエラーを解決する最善の方法は、電源を入れた状態で機器を実行NSZombiesすることです。ゾンビがメッセージを送信されると、Instrumentsはフラグを立て、コード行まで直接遡ることができます。

ユキヒョウが必要ですが、なんと命の恩人でしょう。

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