LLDB - Как распечатать значение глобальной переменной?

В моем случае стек декодируется неправильно, поэтому я не могу использовать команды, связанные с фреймами. Я пытаюсь использовать какое-то абсолютное имя для чтения переменной из определенного модуля.

Мне удалось найти переменную:

(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

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 526
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если бы у вас была отладочная информация для символа, который вы пытаетесь напечатать, то ваши попытки "напечатать" сработали бы. Но не похоже, что у вас есть отладочная информация для библиотеки с этим символом, иначе image lookup -v напечатал бы определяющий модуль компиляции.

Однако у вас есть символ для него (который нашел ваша команда image lookup -v). Таким образом, вы должны иметь возможность распечатать значение из символа.

Проблема в том, что если вы дадите lldb расшифрованное имя os::_mem_serialize_page, он начнет с попытки найти «os» (чтобы он мог найти _mem_serialize_page в этом классе или пространстве имен). Поскольку типов нет, он ничего не будет знать о « os", и на этом остановимся.

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

Однако нет способа сообщить lldb тип переменной. Без отладочной информации lldb не может узнать тип и не может напечатать значение, не зная этого.

Извините, что запутал вас, я скопировал информацию о модуле с image lookup -v. Конечно, у меня есть отладочная информация, иначе image lookup -v ее бы не нашел. Изменение символов — интересный момент. Знаете ли вы, как обойти это и убедить LLDB взять искаженное имя? В противном случае это все еще поэтапный процесс, которого я бы предпочел избежать.

Codeguard 23.01.2019 16:01
image lookup -v -s будет искать имена символов, а также отладочную информацию, поэтому тот факт, что он нашел os::_mem_serialize_page, не означает, что у вас есть отладочная информация для libjvm.dylib или для этой ее части в любом случае. Если бы у вас была информация об отладке, для CompileUnit должна была быть еще одна запись. Ты и это сфоткал?
Jim Ingham 23.01.2019 21:38

Используя подсказку Jim Ingham относительно image lookup -v, я понял, что переменную можно прочитать, используя искаженное имя:

  1. Определите искаженное имя:
(lldb) image lookup -v -s os::_mem_serialize_page libjvm.dylib
<snip> name = "os::_mem_serialize_page", mangled = "_ZN2os19_mem_serialize_pageE" <snip>
  1. Отныне это имя можно использовать для чтения переменной
(lldb) p _ZN2os19_mem_serialize_pageE
(void *) $5 = 0x0000000000000000

Другие вопросы по теме