tracking a segmentation fault

K

Koen

Hi,

I am trying to track a segmentation fault (EXC_BAD_ACCESS) that's
happening in a program I use on Mac OS X (not my own code). The reason
for the fault is that the default stack on Mac OS X is small. If I
call 'unlimit stack' before I start the program, there is no error.
However, I would like to avoid typing ulimit stack every time.

Examining the code indicates that 2 large static arrays are defined
outside main() as well as many array's inside main():

static int myarray[20][10000];
static int anotherarray[20][10000];

int main (int argc, char **argv)
{
int labels[20];
int names[20][10000];
float num[20][10000];
.....


So, after some reading, I understand I can add something like this to
the code, to increase the stack:

struct rlimit rlim;
getrlimit(RLIMIT_STACK, &rlim);
rlim.rlim_cur = RLIM_INFINITY;
setrlimit(RLIMIT_STACK, &rlim);

Unfortunately, even if I put this right after int main (int argc, char
**argv), I still get the error. If I use gdb, I immediately drop in
the error after main() starts. So I suspect the compiler is creating
all the array's first, using all the available stack.

Is there a way to modify the code so that the 'rlimit' snippit is
called before everything else happens? Or maybe I need to use
different compiler settings?


thanks,


- Koen.
 
M

Mark A. Odell

(e-mail address removed) (Koen) wrote in

Hi,

I am trying to track a segmentation fault (EXC_BAD_ACCESS) that's
happening in a program I use on Mac OS X (not my own code). The reason
for the fault is that the default stack on Mac OS X is small. If I
call 'unlimit stack' before I start the program, there is no error.
However, I would like to avoid typing ulimit stack every time.

Examining the code indicates that 2 large static arrays are defined
outside main() as well as many array's inside main():

static int myarray[20][10000];
static int anotherarray[20][10000];

int main (int argc, char **argv)
{
int labels[20];
int names[20][10000];
float num[20][10000];
.....


So, after some reading, I understand I can add something like this to
the code, to increase the stack:

struct rlimit rlim;
getrlimit(RLIMIT_STACK, &rlim);
rlim.rlim_cur = RLIM_INFINITY;
setrlimit(RLIMIT_STACK, &rlim);

This is not a C thing. I think you would be much better served
malloc()'ing the memory you need rather than increasing the stack size.
 
B

bd

Koen said:
Hi,

I am trying to track a segmentation fault (EXC_BAD_ACCESS) that's
happening in a program I use on Mac OS X (not my own code). The reason
for the fault is that the default stack on Mac OS X is small. If I
call 'unlimit stack' before I start the program, there is no error.
However, I would like to avoid typing ulimit stack every time.

Examining the code indicates that 2 large static arrays are defined
outside main() as well as many array's inside main():

static int myarray[20][10000];
static int anotherarray[20][10000];

int main (int argc, char **argv)
{
int labels[20];
int names[20][10000];
float num[20][10000];
.....


So, after some reading, I understand I can add something like this to
the code, to increase the stack:

struct rlimit rlim;
getrlimit(RLIMIT_STACK, &rlim);
rlim.rlim_cur = RLIM_INFINITY;
setrlimit(RLIMIT_STACK, &rlim);

Unfortunately, even if I put this right after int main (int argc, char
**argv), I still get the error. If I use gdb, I immediately drop in
the error after main() starts. So I suspect the compiler is creating
all the array's first, using all the available stack.

Is there a way to modify the code so that the 'rlimit' snippit is
called before everything else happens? Or maybe I need to use
different compiler settings?

Changing the size of the stack is off-topic here. However, I'd change
names[][] and num[][] to be allocated from the malloc() pool - usually it's
much larger than the stack.
 
M

Mark McIntyre

Hi,

I am trying to track a segmentation fault (EXC_BAD_ACCESS) that's
happening in a program I use on Mac OS X (not my own code). The reason
for the fault is that the default stack on Mac OS X is small.

most implementations limit the amount of auto variables you can have.
You are obviously exceeding that.

There may be a system specific way to avoid the problem (ask in an OSX
programming group please), but the usual C answer is NOT to use huge
fixed-size arrays, but malloc the memory instead.

int *p = malloc(200000 * sizeof *p);
 
K

Koen

Mark McIntyre said:
There may be a system specific way to avoid the problem (ask in an OSX
programming group please),

Ahh - sorry, I didn't realize the setrlimit call was OS specific.
but the usual C answer is NOT to use huge
fixed-size arrays, but malloc the memory instead.


Anyway, it got solved by creating a new main() function which
increases the stacksize and then calls the original main() function.

So, a semi-C solution and more or less on-topic :)


- Koen.
 
D

DBTID

Koen said:

For future reference, this would have been best posted in
comp.unix.programmer. I'd set follow-ups to go there, but I don't
know how with the tool I"m using.
I am trying to track a segmentation fault (EXC_BAD_ACCESS) that's
happening in a program I use on Mac OS X (not my own code). The reason
[snip]

static int myarray[20][10000];
static int anotherarray[20][10000];
int main (int argc, char **argv)
{
int labels[20];
int names[20][10000];
float num[20][10000];
.....
So, after some reading, I understand I can add something like this to
the code, to increase the stack:
struct rlimit rlim;
getrlimit(RLIMIT_STACK, &rlim);
rlim.rlim_cur = RLIM_INFINITY;
setrlimit(RLIMIT_STACK, &rlim);

OK, since we're in comp.lang.c and tradition says we must be pedantic,
I will start off by pointing out that the C language has no concept of
a stack. That's an OS or a machine architecture concept. There are
some architectures where this would run just fine because local
variables are allocated as part of the overall memory the program
uses (System\370 works this way) and the PowerPC could be made to
run this way if it weren't for the ABI conventions.

But, practically speaking, your implementation has a stack, and yes
you're most likely trashing it long before you get to call setrlimit.
The entrance to main is going to allocate the stack space necessary
for those locals and you end up with your fault.

There are three ways to solve this that spring immediately to mind:

1) Use malloc for names and num. 'int **names; float **num;' and
malloc them properly.
2) Move names and num to be outside of main().
Yes, you're making them global.
3) Look up exec(3). Using your setrlimit idea, set the stack to
RLIM_INFINITY and then exec the existing program unmodified.
Read the man page on exec to see why this is.

[snip]

Hope this helps.

dbtid
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top