2013-10-12 11 views
13

どちらもこれらの文の一つがLLDBによって処理することができます...なぜそれはそれは表現コマンドと思われNSStringの結果を思い付くとLLDBがこの式を評価できないのはなぜですか?

expr -o -- [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"] 

po [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"] 

Picture of problem here

答えて

7

を、それをプリントアウトすることができませんlldbでは、通常、可変引数リスト で関数を評価することはできません。それも、簡単なC関数で失敗します。

int foo(char *msg, ...) 
{ 
    return 17; 
} 
 
(lldb) expr foo("bar") 
(int) $2 = 17 

(lldb) expr foo("bar", 2) 
error: no matching function for call to 'foo' 
note: candidate function not viable: requires 1 argument, but 2 were provided 
error: 1 errors parsing expression 

だから、これはlldbのバグ(または非機能)のように見えます。

8

これは実際的な関心事よりも学問的ですが、元の質問とMartinの答えは実際には異なる原因があります。どちらの場合でも、lldbは実際には宣言されているよりも多くの引数を持つ関数を呼び出すことを正しく拒否していますが、異なる理由で実際の定義が間違っています。最初のケースで

、lldbは、実際のメソッド呼び出し[NSStringのstringWithFormat:フォーマット、...]のデバッグ情報を持っていません。コンパイラはあなたのプログラムUSESで定義されているすべての関数のデバッグ情報を出力しません。この制限は、主にデバッグ情報のサイズを管理しやすくすることです。

ので、デバッガは、これらのキットの機能のための余分なタイプの情報のためにObjCランタイムに相談する必要があります。しかし、実行時型情報は、可変引数関数の可変引数をエンコードしません。第2のケースで

、何を見ていると、実際に打ち鳴らすのデバッグ出力のバグです。この関数が可変引数関数であることをデバッガに知らせるビットの情報は出力されません。いずれの場合においても

は、lldbであなたは「exprの接頭辞」ファイルを使用してlldbの表現パーサーに一般的に使用される関数の宣言を導入することで、問題のこの種のを回避することができます。

その後
extern "C" int foo (char *msg, ...); 

lldbで、私は:例えば、マーティンの場合には、私が「/tmp/expr-prefix.lldb」を含む行のファイルを作る

(lldb) settings set target.expr-prefix /tmp/expr-prefix.lldb 

そして、あなたのことができ式パーサーで関数を呼び出します。この機能にはいくつかの注意点があります。この "expression prefix"ファイルは、 "print"コマンドで実行するすべての式に含まれているので、あまりにも多くのものを置かないでください。そうしないと、一般的な式の解析が遅くなります。これは、デバッガが知らないの#defineのセット全体に依存するため - 非常に遅くなり、おそらくとにかく動作しません

#import <Cocoa/Cocoa.h> 

:ようなことをしようとしないでください。

しかし、あなたはあなたが本当に呼び出す必要があり、このようないくつかの機能を持っている場合、それは非常に参考にすることができ、私たちはどちらかの署名を知らないことができないためか、何とかそれは間違って取得しています。

lldbがにObjC++としての表現を解析するためにextern "C" が必要です。

ObjCメソッドのプロトタイプを作成するには、そのメソッドのプロトタイプを作成するクラスの拡張でそれを実行する必要があります。我々はしばしば初歩的なクラスdef'nを持っており、コンパイラは既知のクラスにメソッドを追加するのを好まず、拡張だけをします。

+0

を働いていましたか?あなたのようなクラス拡張を追加しようとしましたが、試行錯誤はどこにもありません。 1つの試み: 'expr @interface NSPredicate(NSPredicateExt) - (NSString *)predicateFormat; +(NSPredicate *)predicateWithFormat:(NSString *)predicateFormatの引数:(va_list)argList; @end NSPredicate * $ tmpPred = [NSPredicate predicateWithFormat:@ "location!=%@"、self.location]; ' – Jeff

6

私はこの記事の回避策が見つかりました:私は、メソッドを呼び出すために、この構文を使用しようとすると、例えば http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/

を:

po [NSString stringWithFormat:@"%@", @"MyName"]; 

デバッガエラーは次のとおりです。

error: too many arguments to method call, expected 1, have 2 
error: 1 errors parsing expression 

しかし、あなたはこれを試すことができます:

po [[NSString alloc] initWithFormat:@"%@", @"MyName"]; 

デバッガのメッセージは次のとおりです。デバッガで

$4 = 0x0a6737f0 MyName 
+0

Xcode 7.3では、あなたの答えはそれ以上は機能しません。 '(lldb)po [[NSString alloc] initWithFormat:@"%@ "、@" MyName "]; エラー:実行が中断された、理由:EXC_BAD_ACCESS(コード= 1、アドレス= 0x6e756f70)。 プロセスは式評価の前の状態に戻りました。 ' –

4

輸入UIKitは、このジム、あなたはObjective-Cのメソッドのための特定のインラインlldb構文の例を与えることができ、万が一、私のため

expr @import UIKit 
+0

私も!私は理由は分かりませんが。 – Darren

+0

このコマンドは命の恩人です:) –

+0

あなたは本当にクールです。できます。 –

関連する問題