且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么我在这里遇到分段错误?

更新时间:2022-10-19 17:16:22

> mprotect()尚未映射的页面。您应该检查返回代码: mprotect()可能会返回-1,并将 errno 设置为 ENOMEM (这在 mprotect( 2)手册页)。



堆栈页面按需映射,但内核足够聪明以区分页面错误由于当前堆栈指针处于或高于当前堆栈指针的访问(这是由于向下扩展堆栈,通过递减堆栈指针,然后对新值执行读取或写入某个正偏移而导致的有效尝试)和页面错误由堆栈指针下方的访问引起(无效)。


I have the following code, where I try to write something into the stack. I write at the bottom of the stack, which the application still hasn't touched (Note that stack grows downwards and stackaddr here points to the bottom).

However I get segmentation fault even after doing mprotect to give both write and read permissions to that memory region. I get segmentation fault even if I use the compilation flag -fno-stack-protector. What is happening here?

pthread_attr_t attr;
void * stackaddr;
int * plocal_var;
size_t stacksize;

pthread_getattr_np(pthread_self(), &attr);
pthread_attr_getstack( &attr, &stackaddr, &stacksize );

printf( "stackaddr = %p, stacksize = %d\n", stackaddr, stacksize );

plocal_var = (int*)stackaddr;
mprotect((void*)plocal_var, 4096, PROT_READ | PROT_WRITE);
*plocal_var = 4;
printf( "local_var = %d!\n", *plocal_var );

You are almost certainly trying to mprotect() pages which are not yet mapped. You should check the return code: mprotect() is probably returning -1 and setting errno to ENOMEM (this is documented in the mprotect(2) man page).

Stack pages are mapped on demand, but the kernel is clever enough to distinguish between page faults caused by an access at or above the current stack pointer (which are caused by valid attempts to expand the stack downwards, by decrementing the stack pointer, and then performing a read or write to some positive offset from the new value), and page faults caused by an access below the stack pointer (which are not valid).