Почему LLDB не может оценить это выражение?

Ни один из этих операторов не может обрабатываться LLDB... почему он не может найти результат NSString и распечатать его

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

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

Picture of problem here

Ответ 1

Кажется, что команда выражение в 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.

Ответ 2

Это скорее академический, чем практический интерес, но исходный вопрос и ответ Мартина на самом деле имеют разные причины. В обоих случаях lldb на самом деле правильно отказывается вызывать функцию с большим количеством аргументов, чем она объявлена, но получение фактического определения неверно по разным причинам.

В первом случае lldb фактически не имеет отладочной информации для вызова метода [NSString stringWithFormat: format,...]. Оказывается, компилятор не генерирует отладочную информацию для каждой функции, которую использует ваша программа, только те, которые она определяет. Это ограничение в основном заключается в том, чтобы сохранить размер информации отладки управляемой.

Таким образом, отладчик должен проконсультироваться с временем выполнения ObjC для дополнительной информации о типе для этих функций набора. Но информация типа времени выполнения не кодирует переменную аргумент переменных функций аргументов.

Во втором случае то, что вы видите, на самом деле является ошибкой в ​​отладочном выходе clang. Он не может выдавать бит информации, которая сообщает отладчику, что функция является переменной аргументом.

В любом случае, в lldb, вы можете обойти эту проблему, введя объявления общеупотребительных функций в lsb-парсер выражения, используя файл expr-prefix. Например, в случае Мартина я создаю файл "/tmp/expr-prefix.lldb", содержащий строку:

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

Тогда в lldb я делаю:

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

И затем вы можете вызвать функцию в парсере выражения. Несколько предостережений с этой функцией. Этот файл префикса выражения включается во все выражения, которые вы выполняете с помощью команды "print", поэтому не кладите туда слишком много материала или это замедлит общий синтаксический анализ выражений. Не пытайтесь делать такие вещи, как:

#import <Cocoa/Cocoa.h>

который будет очень медленным и, вероятно, не сработает - так как это зависит от целого набора #defines, о котором отладчик не знает.

Но это может быть очень полезно, если у вас есть несколько таких функций, которые вам действительно нужно вызывать, но не могут, потому что мы либо не знаем подпись, либо как-то ошибаемся.

Внешний символ "C" требуется, поскольку lldb анализирует выражения как ObjС++.

Если вы хотите прототипировать метод ObjC, вам нужно сделать это на расширении класса, для которого вы прототипируете метод; у нас часто есть рудиментарный класс def'n, и компилятор не любит добавлять методы к известному классу, только расширения.

Ответ 3

Я нашел обходное решение в этой статье: 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

Ответ 4

импортировать UIKit в отладчик, это сработало для меня

expr @import UIKit