30

これが私の2行のコードです。

NSString *frontFilePath = [[NSBundle mainBundle] pathForResource:[self.bookendFileNames objectAtIndex:self.randomIndex] ofType:@"caf"];
NSLog(@"frontFilePath = %@", frontFilePath );

2行目にブレークポイントを設定し、そこに印刷しようとします。

(lldb) po frontFilePath

しかし、次のエラーが発生します。

error: variable not available

NSLogステートメントをステップオーバーすると、変数が実際にコンソールに出力されるため、混乱しています。

最初の行はNULLを返すことがあるので、その価値についてはデバッグしようとしていますが、現時点ではその理由を理解できません。

4

3 に答える 3

45

これは、最適化されたコードのデバッグの成果物です。ビルド設定でコンパイラーの最適化が有効になっている場合、コンパイラーは、最適であると判断したときに、メモリーとレジスターの間で変数を移動します。lldbで変数を調べている時点では、まだ表示できるはずのように見えても、レジスターやメモリーにまったく存在しない可能性があります。

コンパイラが出力するデバッグ情報の欠点である可能性があります。コンパイラーは、使用するために変数をレジスターにコピーし、デバッグ情報にそのレジスターの場所のみをリストする場合があります。その後、レジスターは他の用途に再利用されます。値はまだスタックに存在しますが、コンパイラーは、値がスタックにあることをデバッガーに通知していません。

デバッグ情報が不十分であるかどうか、またはその特定の命令に値が本当に存在しないかどうかを実際に判断する唯一の方法は、アセンブリコードを手動で調べることです。コンパイラで最適化をオンにするとすぐに、ソースコードは、特定の順序で実際に実行されているものに対する弱い見方になります。

最適化されたコードデバッグの奇抜な世界に迷い込むのではなく、可能であれば、ビルドの最適化(ビルド設定の最適化レベル)をオフにして、その方法でデバッグすることを強くお勧めします。最適化を使用してアプリをデバッグする必要がある場合は、Xcodeでサポートされている最新のApple LLVMコンパイラを使用してビルドしていることを確認してください。最適化されたコードのデバッグを改善するために常に作業が行われており、最大限に活用したいと考えています。あなたができるツールをデートする。

于 2012-10-24T01:27:56.390 に答える
3

診断の「アドレスサニタイザー」も変数の値を使用できなくしているようです。

スキーム>実行>診断>アドレスサニタイザー

于 2020-09-02T15:13:58.433 に答える
2

Swiftでは、Xcode 9から始まり、Xcode 10でも問題が発生する可能性があります。これは、ビルド設定でコードの最適化がオフになっている場合でも発生する可能性があります。@carlos_msがここで指摘しているように、一時的な解決策は、変数を可変として定義することです。

振り向く

let foo = Bar().string

の中へ

var foo = Bar().string

この変数で最適化をスキップさせるため。これはすべての場合に機能するとは限らないことに注意してください。

この場合、古き良き時代debugPrint()があなたを助けるかもしれません。

于 2018-11-12T11:29:58.473 に答える