В моем случае стек декодируется неправильно, поэтому я не могу использовать команды, связанные с фреймами. Я пытаюсь использовать какое-то абсолютное имя для чтения переменной из определенного модуля.
Мне удалось найти переменную:
(lldb) image lookup -s os::_mem_serialize_page libjvm.dylib
Address: libjvm.dylib[0x00000000009bd690] (libjvm.dylib.__DATA.__common + 151184)
Summary: libjvm.dylib`os::_mem_serialize_page
Однако я не понимаю, как прочитать его значение
(lldb) print os::_mem_serialize_page
error: use of undeclared identifier 'os'
(lldb) print libjvm.dylib`os::_mem_serialize_page
error: use of undeclared identifier 'libjvm'
(lldb) x/g libjvm.dylib[0x00000000009bd690]
error: invalid start address expression.
error: address expression "libjvm.dylib[0x00000000009bd690]" evaluation failed
Единственный способ, который я нашел
Найти адрес, подход 1
(lldb) image lookup -v -s os::_mem_serialize_page libjvm.dylib
Address: libjvm.dylib[0x00000000009bd690] (libjvm.dylib.__DATA.__common + 151184)
Summary: libjvm.dylib`os::_mem_serialize_page
Module: <snip>
Symbol: id = {0x0000e81e}, range = [0x000000010ee46690-0x000000010ee46698), name = "os::_mem_serialize_page", mangled = "_ZN2os19_mem_serialize_pageE"
Найти адрес, подход 2
(lldb) image dump symtab libjvm.dylib
Index UserID DSX Type File Address/Value Load Address Size Flags Name
------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ----------------------------------
[59422] 59422 Data 0x00000000009bd690 0x000000010ee46690 0x0000000000000008 0x001e0000 os::_mem_serialize_page
Чтение памяти по адресу, чтобы получить значение переменной
(lldb) x/g 000000010ee46690
0x10ee46690: 0x0000000000000000
Но это неудобно, потому что это требует нескольких шагов, и я должен сам указать тип переменной.
Если бы у вас была отладочная информация для символа, который вы пытаетесь напечатать, то ваши попытки "напечатать" сработали бы. Но не похоже, что у вас есть отладочная информация для библиотеки с этим символом, иначе image lookup -v
напечатал бы определяющий модуль компиляции.
Однако у вас есть символ для него (который нашел ваша команда image lookup -v
). Таким образом, вы должны иметь возможность распечатать значение из символа.
Проблема в том, что если вы дадите lldb расшифрованное имя os::_mem_serialize_page
, он начнет с попытки найти «os» (чтобы он мог найти _mem_serialize_page в этом классе или пространстве имен). Поскольку типов нет, он ничего не будет знать о « os", и на этом остановимся.
Но если вы дадите lldb искаженное имя, lldb будет искать его прямо в таблице символов и сможет перейти оттуда к адресу. Это отключит один из шагов выше.
Однако нет способа сообщить lldb тип переменной. Без отладочной информации lldb не может узнать тип и не может напечатать значение, не зная этого.
image lookup -v -s
будет искать имена символов, а также отладочную информацию, поэтому тот факт, что он нашел os::_mem_serialize_page
, не означает, что у вас есть отладочная информация для libjvm.dylib или для этой ее части в любом случае. Если бы у вас была информация об отладке, для CompileUnit должна была быть еще одна запись. Ты и это сфоткал?
Используя подсказку Jim Ingham
относительно image lookup -v
, я понял, что переменную можно прочитать, используя искаженное имя:
(lldb) image lookup -v -s os::_mem_serialize_page libjvm.dylib
<snip> name = "os::_mem_serialize_page", mangled = "_ZN2os19_mem_serialize_pageE" <snip>
(lldb) p _ZN2os19_mem_serialize_pageE
(void *) $5 = 0x0000000000000000
Извините, что запутал вас, я скопировал информацию о модуле с
image lookup -v
. Конечно, у меня есть отладочная информация, иначеimage lookup -v
ее бы не нашел. Изменение символов — интересный момент. Знаете ли вы, как обойти это и убедить LLDB взять искаженное имя? В противном случае это все еще поэтапный процесс, которого я бы предпочел избежать.