web-dev-qa-db-ja.com

lldbエラー:変数が利用できません

これが私の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を返すので、最初の行をデバッグしようとしていますが、現時点ではその理由を理解できません。

26
ari gold

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

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

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

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

41
Jason Molenda

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

順番

_let foo = Bar().string
_

_var foo = Bar().string
_

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

この場合、古き良きdebugPrint()が役立つかもしれません。

1
ff10