Reflendey
Всем доброго вечера
Глупый вопрос, но ответа не нашел.
наверное, проще всего пояснить его на возникшем примере. (а иначе я просто внятно и не сформулирую)
(gdb) p/x $ebp
$125 = 0xbffff108
С другой стороны
(gdb) x/8x &wis[128]
0xbffff0f8: 0x00000012 0xbffff130 0x00000000 0xbffff530
0xbffff108: 0xbffff548 0x0804880d 0xbffff130 0xbffff130
ebp должен быть там, но его нет!
нагуглил чисто случайно кусок мануала, где ebp читался так:
(gdb) p/x *(unsigned *) $ebp
$131 = 0xbffff548
И да, теперь ebp нашелся
Но в итоге что за чудеса? По какому принципу вообще определить какой волшебный тип указывать, во избежания такиз недоразумений, и почему сам gdb выводит по p в одном виде, а в x, в другом один и тот же кусок памяти. Опции форматированяи разного и там и там есть же.
Наверное, ответ это где-то содержится в мануале, но где именно?
info registers выводит тоже 0xbffff108.
если гуглить, то для всех очевидно stackoverflow.com/questions/15869168/gnu-gdb-cu... (вот например) что надо выводить именно в таком виде. В других местах сразу выводят "как надо", не поясняя ни капли. Но я чего-то не допонимаю. в ebp лежит адрес, он iзанимает 4 байта и итак int вроде. Что зс ним происходит если явно указать тип? По какому принципу вообще присходит это преобразование:0xbffff108 -> 0xbffff548.
Глупый вопрос, но ответа не нашел.
наверное, проще всего пояснить его на возникшем примере. (а иначе я просто внятно и не сформулирую)
(gdb) p/x $ebp
$125 = 0xbffff108
С другой стороны
(gdb) x/8x &wis[128]
0xbffff0f8: 0x00000012 0xbffff130 0x00000000 0xbffff530
0xbffff108: 0xbffff548 0x0804880d 0xbffff130 0xbffff130
ebp должен быть там, но его нет!
нагуглил чисто случайно кусок мануала, где ebp читался так:
(gdb) p/x *(unsigned *) $ebp
$131 = 0xbffff548
И да, теперь ebp нашелся
Но в итоге что за чудеса? По какому принципу вообще определить какой волшебный тип указывать, во избежания такиз недоразумений, и почему сам gdb выводит по p в одном виде, а в x, в другом один и тот же кусок памяти. Опции форматированяи разного и там и там есть же.
Наверное, ответ это где-то содержится в мануале, но где именно?
info registers выводит тоже 0xbffff108.
если гуглить, то для всех очевидно stackoverflow.com/questions/15869168/gnu-gdb-cu... (вот например) что надо выводить именно в таком виде. В других местах сразу выводят "как надо", не поясняя ни капли. Но я чего-то не допонимаю. в ebp лежит адрес, он iзанимает 4 байта и итак int вроде. Что зс ним происходит если явно указать тип? По какому принципу вообще присходит это преобразование:0xbffff108 -> 0xbffff548.
содержимое регистра $ebp
(gdb) p/x *$ebp
содержимое памяти по адресу в $ebp
Сравни:
(gdb) p/x 0xbffff108
0xbffff108
(gdb) p/x *0xbffff108
0xbffff548
Как-то не подумал, что в случае x показывается содержимое по указанному адресу, хотя это и довольно естественно, и если подумать, то иначе и быть не могло.
Возник правда другой вопрос
на тему почему не работает
(gdb) p/x *$ebp
содержимое памяти по адресу в $ebp
Выдает
Attempt to dereference a generic pointer.
Понятно, что ему как раз не нравится тип (по дефолту (void *))
И можно привести его к (int *) и все будет хорошо.
Но разве в ebp, при нормальном его использовании (то есть программа на 32битной платформе, написанная на си, а не некто на ассемблере использует регистры как хочет) может оказаться что-то кроме указателя на 4байтовую область памяти? Тогда почему же gdb не учитывает это? (причем я так понимаю, вопрос о трактовке этой этого указателя тоже не стоит, отрицательных чисел там быть не может и ясно что это unsigned)
а сам не знаю
с другими регистрами работает без капризов
ниже пример, когда в rsi и rbp одинаковое значение
(gdb) p/x $rsi
$3 = 0x7fffffffe0c4
(gdb) p/x $rbp
$4 = 0x7fffffffe0c4
(gdb) p/x *$rbp
Attempt to dereference a generic pointer.
(gdb) p/x *$rsi
$5 = 0x0
(gdb) p/x *0x7fffffffe0c4
$7 = 0x0
Как-то не подумал, что в случае x показывается содержимое по указанному адресу, хотя это и довольно естественно, и если подумать, то иначе и быть не могло.
Возник правда другой вопрос
на тему почему не работает
(gdb) p/x *$ebp
содержимое памяти по адресу в $ebp
Выдает
Attempt to dereference a generic pointer.
Понятно, что ему как раз не нравится тип (по дефолту (void *))
И можно привести его к (int *) и все будет хорошо.
Но разве в ebp, при нормальном его использовании (то есть программа на 32битной платформе, написанная на си, а не некто на ассемблере использует регистры как хочет) может оказаться что-то кроме указателя на 4байтовую область памяти? Тогда почему же gdb не учитывает это? (причем я так понимаю, вопрос о трактовке этой этого указателя тоже не стоит, отрицательных чисел там быть не может и ясно что это unsigned)
Второй вопрос я задал еще на форуме курсеровского курса, но он какой-то очень вялый, так что едва ли кто-то ответит, но если вдруг - напишу сюда.