Odd C stack behavior

I am using Hope functional program on Ubuntu 14.04 with gcc 4.8.2 and am doing a highly recursive function to find a large number of primes. However, I am getting segmentation error: 0x000000000040e03f in reaching

cell=<error reading variable: Cannot access memory at address 0x7fffff7feff8> at runtime.c:250

      

A segmentation fault occurs when accessing address 0x7fffff7feff8.

What the pick routine does is mark up the heap items that can be reached by the current expression (using garbage mark markup). The stack is very deep (100000 + calls), but there is no stack overflow:

base_memory = 0x7ffff35a4010
top_string = 0x7ffff35a5260
BaseHeap = 0x7ffff35a5260
heap = 0x7ffff603a450
stack = 0x7ffff72da498
TopStack = 0x7ffff7584d60

      

In the area from base_memory to TopStack, malloc is allocated.

Whenever I get a segment violation, the address is always 0x7fffff7feff8, even with very different functions.

If you are using google 0x7fffff7feff8 there are quite a few segment violation records with this address without fixing the problem.

I put in a code to check that the heap address is in the range of the heap, but it never worked.

I did gdb

find 0x7ffff35a4010,0x7ffff7584d60,0x7fffff7feff8

      

and nothing was found.

Why 0x7fffff7feff8

does the address appear in so many problems? Is there something wrong with the stack mechanism, or do I need to somehow change the code for the platform?

+3


source to share


1 answer


It is more like a stack overflow on an x86-64 system without address allocation randomization. If the stack starts at 0x7ffffffff000

, as in such systems, it 0x7fffff7feff8

suspiciously approaches 8 MB below the start of the stack, which is the common standard thread stack size on Linux systems.

Flush the contents /proc/self/maps

and check if the beginning of the stack matches (it is listed at the bottom) and check ulimit -s

to see how new processes come out in stack size. If it /proc/self/maps

enumerates 0x7ffffffff000

as the end of a range of stack addresses, but ulimit -s

prints 8192

, then you have just a stack overflow. In this case, a quick solution would be to increase the stack size of new processes (active shell subprocesses) as follows:

ulimit -Ss size_in_kilobytes

      



This will work up to a hard limit root

, which may or may not be enforced. Ultimately it would be nice to rewrite the code in a less recursive way.

Also, if this all hits the house, you should probably enable ASLR ( sysctl kernel.randomize_va_sapce=1

). If this complains, your system desperately needs an update. Write kernel.randomize_va_space = 1

to /etc/sysctl.conf

to make it permanent).

+4


source







All Articles