web-dev-qa-db-ja.com

LLDBデバッガーでメソッドを呼び出す、またはコードを実行する方法

ブレークポイントまたはprint someFloatVariableを設定するときにpo [self someIvarHoldingAnObject]と入力できることは知っていますが、次のような便利なことはできません。

[self setAlpha:1];

それから吐き出します:

エラー:「[self」は有効なコマンドではありません。

奇妙なことは、po [self someIvarHoldingAnObject]を呼び出すことができ、その説明を出力することです。

私は1年前に誰かが実行時にコンソールを介してコードを実行する方法を示したビデオを見たと信じています。どうやってするか?

60
Proud Member

Gdb v。lldbコマンドの標準的なリファレンスは http://lldb.llvm.org/lldb-gdb.html です

式を評価するexprコマンドを使用します。引数に加えて「生の入力」をとるlldbコマンドの1つであるため、(exprへの)引数の終わりとコマンドの開始位置を示すために「-」が必要になることがよくあります。例えば.

(lldb) expr -- [self setAlpha:1]

ショートカット "p"があります。これは、あなたのために(ただし、引数を許可しません)、たとえば.

(lldb) p [self setAlpha:1]

呼び出している関数がプログラムの一部ではない場合、lldbがそれらの呼び出し方法を認識できるように、戻り値の型を明示的に宣言する必要があることがよくあります。例えば.

(lldb) p printf("hi\n")
error: 'printf' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (int)printf("hi\n")
(int) $0 = 3
hi
(lldb)

浮動小数点引数の問題、BTWを回避する適切な方法があります。クラス式のプロトタイプを使用して、lldbに入力するすべての式に追加される「式プレフィックス」ファイルを作成します。たとえば、NSObjectを継承するクラスMyClassがあり、対象の2つのメソッド「setArg:」と「getArg」があり、float ivarを設定および取得します。これはばかげた小さな例ですが、使用方法を示しています。 lldb用に作成したプレフィックスファイルは次のとおりです。

@interface NSObject
@end
@interface MyClass : NSObject
- init;
- setArg: (float)arg;
- (float) getArg;
@end

extern "C" {
  int strcmp (const char *, const char *);
  int printf(const char * __restrict, ...);
  void puts (const char *);
}

私の~/.lldbinit追加するファイル

settings set target.expr-prefix /Users/jason/lldb-prefix.h

そして今、私はできる

(lldb)    p [var getArg]
(float) $0 = 0.5
(lldb)    p [var setArg:0.7]
(id) $1 = 0x0000000100104740
(lldb)    p [var getArg]
(float) $2 = 0.7

ここにもいくつかの標準Cライブラリ関数が含まれています。これを行った後、これらの戻り値の型をキャストする必要はもうありません。

(lldb) p printf("HI\n")
<no result>
HI
(lldb) p strcmp ("HI", "THERE")
(int) $3 = -12

(その「<結果なし>」問題の修正は、lldb TOTソースに既にコミットされています。)

101
Jason Molenda

複数行が必要な場合は、expressionを使用します。

expression

do {
  try thing.save()
} catch {
  print(error)
}

// code will execute now

コードを終了して実行するための空白行。

4
João Souza