1. ホーム
  2. cocoa

[解決済み] EXC_BREAKPOINT(SIGTRAP)」例外はデバッグ用ブレークポイントが原因か?

2023-03-23 07:14:34

質問

すべてのテスト マシンで非常に安定しているマルチスレッド アプリがあり、ほぼすべてのユーザーで安定しているようです (クラッシュの苦情がないことに基づく)。 しかし、あるユーザーはアプリが頻繁にクラッシュし、そのユーザーはクラッシュ レポートを送信してくれました。 すべてのクラッシュ レポート (~10 回の連続したレポート) は、基本的に同じように見えます。

Date/Time:       2010-04-06 11:44:56.106 -0700
OS Version:      Mac OS X 10.6.3 (10D573)
Report Version:  6

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   com.apple.CoreFoundation        0x90ab98d4 __CFBasicHashRehash + 3348
1   com.apple.CoreFoundation        0x90adf610 CFBasicHashRemoveValue + 1264
2   com.apple.CoreText              0x94e0069c TCFMutableSet::Intersect(__CFSet const*) const + 126
3   com.apple.CoreText              0x94dfe465 TDescriptorSource::CopyMandatoryMatchableRequest(__CFDictionary const*, __CFSet const*) + 115
4   com.apple.CoreText              0x94dfdda6 TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const + 40
5   com.apple.CoreText              0x94e00377 TDescriptor::CreateMatchingDescriptors(__CFSet const*, unsigned long) const + 135
6   com.apple.AppKit                0x961f5952 __NSFontFactoryWithName + 904
7   com.apple.AppKit                0x961f54f0 +[NSFont fontWithName:size:] + 39

(...さらにテキストが続きます)

最初に、私は長い時間をかけて[NSFont fontWithName:size:]を調査しました。 私は、おそらくユーザーのフォントが何らかの形でめちゃくちゃになっており、[NSFont fontWithName:size:] が存在しないものを要求し、そのために失敗しているのだと考えました。 私は、[[NSFontManager sharedFontManager] availableFontNamesWithTraits:NSItalicFontMask] を使って、事前にフォントの有無をチェックするコードを大量に追加してみました。 悲しいことに、これらの変更では問題は解決されませんでした。

今になって、_NSLockError、[NSException raise]、および objc_exception_throw などのいくつかのデバッグ用ブレークポイントを削除するのを忘れていたことに気づきました。 しかし、アプリは間違いなく "Release" をアクティブなビルド構成として使用してビルドされています。 しかし、ブレークポイントがどのように機能するのか、またはブレークポイントが効果を発揮するためにプログラムを gdb 内で実行する必要があるのかについては、正確にはわかりません。

私の質問は、ブレークポイントを設定したままにしておくことが、ユーザーによって観察されたクラッシュの原因である可能性があるかどうかということです。 もしそうなら、なぜブレークポイントはこの 1 人のユーザーだけに問題を引き起こすのでしょうか? そうでない場合、[NSFont fontWithName:size:] で同様の問題が発生した人は他にいますか?

私はおそらく、ブレークポイントを削除してユーザーに送り返すことを試してみますが、そのユーザーにどれだけの通貨が残っているのかわかりません。 また、ブレークポイントを設定したままにしておくと問題が発生する可能性があるかどうか (アプリが "Release" 構成を使用して構築されている場合)、より一般的に理解したいと思います。

どのように解決するのですか?

EXC_BREAKPOINT (SIGTRAP)」例外は、デバッグ用ブレークポイントによって発生するのでしょうか?

いいえ、実はその逆です。SIGTRAP (トレース トラップ) は、実際のブレークポイントと同じように、デバッガーがプログラムをブレーク (中断) させる原因となります。しかし、これはデバッガーが常にクラッシュ時にブレークするからであり、SIGTRAP (他のいくつかの シグナル など) はクラッシュの一種です。

SIGTRAP は一般に NSExceptions がスローされることで発生しますが、常に発生するわけではありません。 上げる を直接発生させることも可能です。

<ブロッククオート

私は今、_NSLockError、[NSException raise]、および objc_exception_throw を含むいくつかのデバッグブレークポイントを削除するのを忘れていたことに気づきました。

これらはブレークポイントではありません。そのうちの 2 つは関数であり -[NSException raise] はメソッドです。

ブレークポイントを設定するということですか にブレークポイントを設定したということですか?

私は、"Release" 設定を使用すると、ブレークポイントの設定を防ぐことができると仮定しています。

いいえ。

コンフィギュレーションは ビルド 設定です。これらは、Xcodeがアプリケーションを構築する方法に影響を与えます。

ブレークポイントはビルドの一部ではなく、デバッガで設定します。デバッガーの下でプログラムを実行するときだけ存在し、ヒットされ、プログラムを停止します。

ビルドの一部ではないので、アプリのバンドルを与えるだけでは、ユーザーにブレークポイントを渡すことはできません。

ブレークポイントがどのように機能するのか、正確にはわかりません ...

プログラムがブレークポイントに達すると、デバッガはプログラムを中断させます。

プログラムを停止させるのはデバッガなので、デバッガの下でプログラムを実行していないときは、ブレークポイントは何の効果も持ちません。

... あるいは、ブレークポイントを有効にするために、プログラムを gdb 内から実行する必要があるかどうか。

そうです。デバッガ ブレークポイントはデバッガ内でのみ機能します。

私の質問は、ブレークポイントを設定したままにしておいたことが、ユーザーによって観察されたクラッシュの原因である可能性があるかということです。

いいえ。

まず、前述のように、これらのブレークポイントが何らかの形でユーザーのシステムに引き継がれたとしても、ブレークポイントはデバッガーにおいてのみ有効です。プログラムがデバッガーの下で実行されていない場合、デバッガーはブレークポイント上で停止することはできません。ユーザーは、特にクラッシュ ログを取得したことから、ほぼ確実にデバッガーの下でアプリケーションを実行していません。

これらのブレークポイントをすべて設定してデバッガーの下でアプリを実行したとしても、ブレークポイントはプログラムがその時点に到達したときにのみヒットします。 _NSLockError , -[NSException raise] または objc_exception_throw . そのポイントに到達することは、問題の原因ではなく、問題の症状でしょう。

また、これらのいずれかが呼び出された結果としてクラッシュした場合、クラッシュ ログに少なくとも 1 つの名前が記載されているはずです。そうではありません。

Cocoa の例外は SIGTRAP の原因の 1 つですが、それだけではありません。あなたは別のものに遭遇しました。

もしそうでなければ、[NSFont fontWithName:size:] で同様の問題が発生した人は他にいますか?

あなたがクラッシュ ログを切断したため、私たちが経験した問題が類似しているかどうかを判断する方法はありません。クラッシュがどのようなコンテキストで起こったのか、私たちは何も知りません。

私たちは dSYM バンドルを持っていないので、クラッシュ ログを象徴するためにそのセクションを使用することができないことを意味します。

一方、あなたは、できます。私は次のように書きました。 アプリ を書きました。このアプリにクラッシュログを送ると、自動的に DSYM バンドルを検出し (配布するすべての Release ビルドで dSYM バンドルを保持していますね)、関数やメソッドが表示される場所ではスタックトレースに関数名やメソッド名をリストアします。

さらに詳しい情報については Xcode デバッグ ガイド .