DougT
DougT

Reputation: 231

C stack odd behavior

I am using the Hope functional program on Ubuntu 14.04 with gcc 4.8.2, and doing a highly recursive function to find a large number of prime numbers. However, I get a segmentation fault: 0x000000000040e03f in reach

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

The segmentation fault occurs when accessing address 0x7fffff7feff8.

What the reach routine is doing is unmarking heap items that can be reached by the current expression (using a garbage collection mark-sweep). The stack is very deep (100000+ calls), but there is not a stack overflow:

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

The area from base_memory to TopStack was allocated with malloc.

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

If you google 0x7fffff7feff8 there are quite a few entries with segment violations with this address, with no solution to the problem.

I put code into check that the heap address was in the heap range, but it never failed.

I did a gdb

find 0x7ffff35a4010,0x7ffff7584d60,0x7fffff7feff8

and nothing was found.

Why does the address 0x7fffff7feff8 show up in so many problems? Is there something amiss with the stack mechanism, or do I need to change the code in some way for the platform?

Upvotes: 3

Views: 774

Answers (1)

Wintermute
Wintermute

Reputation: 44073

This rather looks like a stack overflow on an x86-64 system without adress space layout randomization. If the stack begins at 0x7ffffffff000, as they do on such systems, 0x7fffff7feff8 is suspiciously close to 8 MB below the beginning of the stack, which is a common default thread stack size on Linux systems.

Dump the contents of /proc/self/maps and check if the start of the stack matches this (it is listed at the bottom), and check ulimit -s to see the stack size new processes get. If /proc/self/maps lists 0x7ffffffff000 as end of the stack address range andulimit -s prints 8192, what you have is simply a stack overflow. In this event, a quick fix would be to increase the stack size of new processes (subprocesses of the active shell) like so:

ulimit -Ss size_in_kilobytes

This will work up to a hard limit root may or may not impose. In the long run, it would probably be a good idea to rewrite the code in a less excessively recursive manner.

Also, if all this hits home, you should probably enable ASLR (sysctl kernel.randomize_va_sapce=1. If that complains, your system is in dire need of an upgrade. Write kernel.randomize_va_space = 1 to /etc/sysctl.conf to make it permanent).

Upvotes: 4

Related Questions