Как вызвать методы или выполнить код в отладчике LLDB?

Я знаю, что могу набрать print someFloatVariable, когда я установил точку останова или po [self someIvarHoldingAnObject], но я не могу делать такие полезные вещи, как:

[self setAlpha:1];

Затем он выплевывает:

error: '[self' не является допустимой командой.

Странно, что я могу позвонить po [self someIvarHoldingAnObject], и он напечатает его описание.

Я считаю, что видел видео год назад, когда кто-то продемонстрировал, как выполнять код через консоль во время выполнения, и если я не ошибаюсь, этот парень также предоставил аргументы и назначил объекты указателям. Как это сделать?

Ответ 1

Каноническая ссылка для команд gdb v. lldb http://lldb.llvm.org/lldb-gdb.html

Вы хотите использовать команду expr, которая вычисляет выражение. Это одна из команд lldb, которая принимает "сырой вход" в дополнение к аргументам, поэтому вам часто требуется "-", чтобы указать, где заканчиваются аргументы (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, с прототипом ваших методов класса. Например, у меня есть класс MyClass, который наследуется от NSObject, он имеет два метода, представляющих интерес: "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

(исправление для этого объекта "< no result > " уже было передано в источники lldb TOT.)

Ответ 2

Если вам нужна многострочная, используйте expression:

expression

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

// code will execute now

Пустая строка для завершения и выполнения кода.