странное поведение стека
ясен пень, что если touch закомментировать, то память не выделяется, а если раскомментировать, то все пучком.
ничего не понял. можно поподробнее? значит "выделяется память"? каким именно способом выделяется? и кем, где, как?
надо думать, при записи в страницу
вообще, недавно в lkml обсуждение было, что на x86 доступ к стеку ниже %esp в общем случае баг, потому что может прийти сигнал, и обработчик его потрёт данные
test = test - 8 * 1024;не заметил, что здесь - . Тогда мне тоже не ясно.
А вообще память выделяется здесь
char A[1024*1024];
При раскомментированном touch естественно.
Да, это именно оно, вся разница в этих 2 случаях в том что доступ ниже %esp.
Давно такое сделали? Я тут попробовал на нескольких машинах - везде одинаковый результат (в том числе и где ядро старое). Буду знать. Спасибо!
Если бы ссылку кинул то было бы вообще супер!
Собственно в том и вопрос, почему 1 Mb выделить дают, а 8 kb - нет.
test = test - 8 * 1024;можно память выделять
в первом случае - выше %esp, во втором - ниже
Я уже понял. Просто при беглом чтении сырцов не видел места не видел места где проверяют адрес ошибки с %esp (да и вообще не думал что такая проверка там может быть). Может кто-нибудь тыкнет пальцем?
do_page_fault
/*
* accessing the stack below %esp is always a bug.
* The "+ 32" is there due to some instructions (like
* pusha) doing post-decrement on the stack and that
* doesn't show up until later..
*/
if (address + 32 < regs->esp)
goto bad_area;
Все, расставил все точки над i
Соответственно, и все её переменные в том числе...
// c=test[0];
память вызываемой функции находится перед вызывающей. Вызовом touch ты обеспечиваешь себе кусок 1024*1024 перед char c; в который можешь спокойно писать. Что и делаешь. Если не вызываешь, то segfault.
перед
мне непонятно.
Я правильно понимаю, что нужно производить запись в ЛОКАЛЬНЫЕ переменные ДРУГОЙ функции?
Если да, то в декларации этих переменных не повредит static. и передача их адресочков через глобальные переменные (или ещё как-нибудь) всем, кому надо..
Теперь я все понял. Точнее не все, но хотя бы что-то.
Tnx
$1 = (char (*)[1048576]) 0xbfaff700
(gdb) step
main at qqq.c:14
14 test = test - 8 * 1024;
(gdb) p &c
$2 = 0xbfbff71f "©|В©©!\204\004\b\001"
Под FreeBSD не падает никак.
Оставить комментарий
Landstreicher
Почему следующая программа падает в сегфолт, однако если раскомментировать вызов touch то все начинает работать нормально:void touch
{
char A[1024*1024];
A[0] = 0;
}
int main
{
char c;
//touch;
char *test = &c;
test = test - 8 * 1024;
c = test[0];
return 0;
}
Только не говорите мне что стек растет вверх