Как найти и проверить стековую память в ОС QNX на ARM64?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как найти и проверить стековую память в ОС QNX на ARM64?

Сообщение Anonymous »

Я хотел бы отобразить содержимое стековой памяти приложения. Это помогло бы мне понять управление памятью в системе и определить скорость заполнения стека (возможно, для оптимизации).
Эта простая программа создает поток, который имеет массив в качестве локальной переменной (в своем стеке):

Код: Выделить всё

#include 

int main()
{
std::thread thread{[=]() {
int test[128];

for (int i = 0; i < 128; i++)
{
test[i] = i;
}

while (true)
{
}
}};

thread.join();

return 0;
}
Массив заполнен последовательными числами, и я надеюсь, что смогу найти их при исследовании памяти стека. Теперь запускаю программу и сбрасываю память с помощью дампера (https://www.qnx.com/developers/docs/6.5 ... umper.html). Когда я открываю дамп ядра в GDB, я могу просмотреть области памяти. Например, x/100xw отобразит 100 слов по заданному адресу.
Теперь я проверяю файл pmap процесса, чтобы найти память стека с помощью cat /proc/
/pmap | grep -я складываю. Результат:

Код: Выделить всё

0x0000001a85a94000,0x0000000000080000,0x00081002,0x03,0x0f,0x00000001,0x0000000000000003,0x0000000000000000,0x0000000000080000,0x00001000,0x00000000,0x0000092d,{stack},{sysram}
0x0000001a85b16000,0x0000000000040000,0x00081002,0x03,0x0f,0x00000001,0x0000000000000003,0x0000000000000000,0x0000000000040000,0x00001000,0x00000000,0x0000092d,{stack},{sysram}
Я интерпретирую первую строку как стек основного потока, а вторую строку как стек потока, в котором находится массив. Согласно https://www.qnx.com/developers/docs/8.0 ... /pmap.html, первый столбец содержит виртуальный адрес памяти стека, а второй столбец — размер. 10-й столбец — размер защитной страницы. Эта страница: https://www.qnx.com/developers/docs/8.0 ... MMGT_.html визуализирует структуру памяти процесса и сообщает нам, что в QNX стек растет вниз. Как я могу использовать это для проверки содержимого стека?
Когда я делаю x/1000xw 0x0000001a85b16000 в GDB (

Код: Выделить всё

0x0000001a85b16000
— виртуальный адрес стека потока согласно pmap), я вижу только слова с нулевым шаблоном (

Код: Выделить всё

0x00000000). Я смотрю не в том месте? Каков виртуальный адрес стека на иллюстрации структуры памяти:
[img]https://i.sstatic.net/1Tf4lE3L.png[/img]

Это [b]красная[/b] стрелка (верхняя часть стека), [b]зеленая[/b] стрелка (верхняя часть) защитная страница стека) или [b]фиолетовая[/b] стрелка (нижняя часть защитной страницы стека)?
Если я предполагаю, что виртуальный адрес из файла pmap
представляет собой фиолетовую стрелку, и добавляю размер стека и вычитаю размер защитной страницы следующим образом:

Код: Выделить всё

0x0000001a85b16000 + 0x0000000000040000 - 0x00001000 = 0x1a85b55000
Я должен быть где-то внутри стека. И действительно, если я попробую x/1000xw 0x1a85b55000 в gdb, gdb отобразит сотни нулевых слов, но тогда я смогу найти шаблон массива в дампе ядра:

Код: Выделить всё

...
0x1a85b55630:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b55640:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b55650:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b55660:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b55670:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b55680:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b55690:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b556a0:   0x00000000      0x00000000      0x00000000      0x00000000
0x1a85b556b0:   0x00000000      0x00000000      0xc7ccd180      0x0000005a
0x1a85b556c0:   0x00000000      0x00000080      0x00000000      0x00000001
0x1a85b556d0:   0x00000002      0x00000003      0x00000004      0x00000005
--Type  for more, q to quit, c to continue without paging--
0x1a85b556e0:   0x00000006      0x00000007      0x00000008      0x00000009
0x1a85b556f0:   0x0000000a      0x0000000b      0x0000000c      0x0000000d
0x1a85b55700:   0x0000000e      0x0000000f      0x00000010      0x00000011
0x1a85b55710:   0x00000012      0x00000013      0x00000014      0x00000015
0x1a85b55720:   0x00000016      0x00000017      0x00000018      0x00000019
0x1a85b55730:   0x0000001a      0x0000001b      0x0000001c      0x0000001d
0x1a85b55740:   0x0000001e      0x0000001f      0x00000020      0x00000021
0x1a85b55750:   0x00000022      0x00000023      0x00000024      0x00000025
0x1a85b55760:   0x00000026      0x00000027      0x00000028      0x00000029
0x1a85b55770:   0x0000002a      0x0000002b      0x0000002c      0x0000002d
0x1a85b55780:   0x0000002e      0x0000002f      0x00000030      0x00000031
...
Тем не менее, я явно неправильно интерпретирую расположение памяти. Почему до начала массива в памяти должно быть так много нулевых записей, если вычисленный адрес находился в памяти стека? Тогда какова правильная интерпретация? Как правильно локализовать стек потока в сброшенной памяти? Как я могу вычислить адреса, отмеченные красной, зеленой и фиолетовой стрелкой, на основе информации pmap?

Подробнее здесь: https://stackoverflow.com/questions/798 ... s-on-arm64
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»