Recursion crash in STL on linux

B

boltar2003

Hi

I don't know if this is a gcc C++ implementation issue (I suspect it is) or a
linux issue so I'm hedging my bets by posting to 2 newsgroups.

I have a C++ program for linux that does a LOT of recursion due to searching
etc which I won't bore you with but I am getting consistent crashes in the
STL. This appears to be due to running out of stack or heap space but all
that happens is the container crashes , there is no exception thrown and no way
of knowing when its going to happen. Sure I can limit recursion depth but
it would be nice to know when the stack limit is about to be hit.

So does anyone know a way in linux of checking the amount of stack space or
heap space left for a process (hopefully not something kludgy like attempting
to just malloc a large amount of memory to see what happens) or

is there a way to get around this apparent bug in the STL and make it chuck an
exception if this sort of thing happens?

There are 2 sorts of crashes I'm getting , one is a malloc() failure in new
(doesn't it check for NULL return from malloc??):

Program received signal SIGSEGV, Segmentation fault.
0xb76317e0 in malloc_consolidate () from /lib/libc.so.6
(gdb) bt
#0 0xb76317e0 in malloc_consolidate () from /lib/libc.so.6
#1 0xb76336e5 in _int_malloc () from /lib/libc.so.6
#2 0xb7635545 in malloc () from /lib/libc.so.6
#3 0xb7809d07 in operator new () from /usr/lib/libstdc++.so.6
#4 0x08058e68 in __gnu_cxx::new_allocator<cl_result*>::allocate (
this=0xbf435360, __n=128)
at /usr/lib/gcc/i486-slackware-linux/4.3.3/../../../../include/c++/4.3.3/
ext/new_allocator.h:92
#5 0x08058e92 in std::_Deque_base<cl_result*, std::allocator<cl_result*> >::
_M_allocate_node (this=0xbf435360)


and the other is something rather more obscure though probably related:

Program received signal SIGSEGV, Segmentation fault.
0x08057770 in std::__copy_move<false, false, std::random_access_iterator_tag>
::__copy_m<std::_Deque_iterator<cl_result*, cl_result* const&, cl_result*
const*>, std::_Deque_iterator<cl_result*, cl_result*&, cl_result**> >
(__first=
{_M_cur = 0x9c88b68, _M_first = 0x9c88b68, _M_last = 0x9c88d68, _M_node =
0x9c88464}, __last=
{_M_cur = 0x9c88b68, _M_first = 0x9c88b68, _M_last = 0x9c88d68, _M_node =
0x9c88464}, __result=
{_M_cur = 0xbf5dd088, _M_first = 0x0, _M_last = 0x0, _M_node =
0xbf5dd3c0})
at /usr/lib/gcc/i486-slackware-linux/4.3.3/../../../../include/c++/4.3.3/
bits/stl_algobase.h:340
340 for(_Distance __n = __last - __first; __n > 0; --__n)


Though the actual crash point varies.

Thanks for any help.

B2003
 
F

Fred Zwarts

Hi

I don't know if this is a gcc C++ implementation issue (I suspect it
is) or a linux issue so I'm hedging my bets by posting to 2
newsgroups.

I have a C++ program for linux that does a LOT of recursion due to
searching etc which I won't bore you with but I am getting consistent
crashes in the STL. This appears to be due to running out of stack or
heap space but all
that happens is the container crashes , there is no exception thrown
and no way of knowing when its going to happen. Sure I can limit
recursion depth but
it would be nice to know when the stack limit is about to be hit.

So does anyone know a way in linux of checking the amount of stack
space or heap space left for a process (hopefully not something
kludgy like attempting to just malloc a large amount of memory to see
what happens) or

is there a way to get around this apparent bug in the STL and make it
chuck an exception if this sort of thing happens?

There are 2 sorts of crashes I'm getting , one is a malloc() failure
in new (doesn't it check for NULL return from malloc??):

Yes it does, but as you see in the following, malloc does not return.
There is a SIGSEGV crash in malloc. This is usually not caused by
exhaustion of the heap, but by corruption of the internal heap
administration. This could be due to running out of stack space.
Program received signal SIGSEGV, Segmentation fault.
0xb76317e0 in malloc_consolidate () from /lib/libc.so.6
(gdb) bt
#0 0xb76317e0 in malloc_consolidate () from /lib/libc.so.6
#1 0xb76336e5 in _int_malloc () from /lib/libc.so.6
#2 0xb7635545 in malloc () from /lib/libc.so.6
#3 0xb7809d07 in operator new () from /usr/lib/libstdc++.so.6
#4 0x08058e68 in __gnu_cxx::new_allocator<cl_result*>::allocate (
this=0xbf435360, __n=128)
at
/usr/lib/gcc/i486-slackware-linux/4.3.3/../../../../include/c++/4.3.3/
ext/new_allocator.h:92 #5 0x08058e92 in std::_Deque_base<cl_result*,
std::allocator<cl_result*> >:: _M_allocate_node (this=0xbf435360)


and the other is something rather more obscure though probably
related:

Program received signal SIGSEGV, Segmentation fault.
0x08057770 in std::__copy_move<false, false,
std::random_access_iterator_tag>
const*>, std::_Deque_iterator<cl_result*, cl_result*&, cl_result**> >
(__first=
{_M_cur = 0x9c88b68, _M_first = 0x9c88b68, _M_last = 0x9c88d68,
_M_node = 0x9c88464}, __last=
{_M_cur = 0x9c88b68, _M_first = 0x9c88b68, _M_last = 0x9c88d68,
_M_node = 0x9c88464}, __result=
{_M_cur = 0xbf5dd088, _M_first = 0x0, _M_last = 0x0, _M_node =
0xbf5dd3c0})
at
/usr/lib/gcc/i486-slackware-linux/4.3.3/../../../../include/c++/4.3.3/
bits/stl_algobase.h:340 340 for(_Distance __n = __last
- __first; __n > 0; --__n)


Though the actual crash point varies.

Thanks for any help.

Are you sure that the problem is the stack limit and not another form
of memory corruption? What does the debugger tell you?
 
R

Ralf Fassel

* (e-mail address removed)
| So does anyone know a way in linux of checking the amount of stack space or
| heap space left for a process (hopefully not something kludgy like attempting
| to just malloc a large amount of memory to see what happens) or

On Linux, use valgrind http://valgrind.org/ to see where your program
corrupts the memory as it happens, not afterwards when the SEGV occurs.

R'
 
S

Sjouke Burry

Fred said:
Yes it does, but as you see in the following, malloc does not return.
There is a SIGSEGV crash in malloc. This is usually not caused by
exhaustion of the heap, but by corruption of the internal heap
administration. This could be due to running out of stack space.


Are you sure that the problem is the stack limit and not another form
of memory corruption? What does the debugger tell you?
Last time I had a stack problem, I just wrote a very small
assembler routine, to return the value of the stackpointer.
That value, as the stack became full , moved to zero.
So if your system works likewise, use such a routine to
quit at the right moment, while there is still some left.
 
M

Mickey

Hi

I don't know if this is a gcc C++ implementation issue (I suspect it is) or a
linux issue so I'm hedging my bets by posting to 2 newsgroups.

I have a C++ program for linux that does a LOT of recursion due to searching
etc which I won't bore you with but I am getting consistent crashes in the
STL. This appears to be due to running out of stack or heap space but all
that happens is the container crashes , there is no exception thrown and no way
of knowing when its going to happen. Sure I can limit recursion depth but
it would be nice to know when the stack limit is about to be hit.

So does anyone know a way in linux of checking the amount of stack space or
heap space left for a process (hopefully not something kludgy like attempting
to just malloc a large amount of memory to see what happens) or

is there a way to get around this apparent bug in the STL and make it chuck an
exception if this sort of thing happens?

There are 2 sorts of crashes I'm getting , one is a malloc() failure in new
(doesn't it check for NULL return from malloc??):

Program received signal SIGSEGV, Segmentation fault.
0xb76317e0 in malloc_consolidate () from /lib/libc.so.6
(gdb) bt
#0  0xb76317e0 in malloc_consolidate () from /lib/libc.so.6
#1  0xb76336e5 in _int_malloc () from /lib/libc.so.6
#2  0xb7635545 in malloc () from /lib/libc.so.6
#3  0xb7809d07 in operator new () from /usr/lib/libstdc++.so.6
#4  0x08058e68 in __gnu_cxx::new_allocator<cl_result*>::allocate (
    this=0xbf435360, __n=128)
    at /usr/lib/gcc/i486-slackware-linux/4.3.3/../../../../include/c++/4.3.3/
ext/new_allocator.h:92
#5  0x08058e92 in std::_Deque_base<cl_result*, std::allocator<cl_result*> >::
_M_allocate_node (this=0xbf435360)

and the other is something rather more obscure though probably related:

Program received signal SIGSEGV, Segmentation fault.
0x08057770 in std::__copy_move<false, false, std::random_access_iterator_tag>
::__copy_m<std::_Deque_iterator<cl_result*, cl_result* const&, cl_result*
const*>, std::_Deque_iterator<cl_result*, cl_result*&, cl_result**> >
(__first=
      {_M_cur = 0x9c88b68, _M_first = 0x9c88b68, _M_last = 0x9c88d68, _M_node =
0x9c88464}, __last=
      {_M_cur = 0x9c88b68, _M_first = 0x9c88b68, _M_last = 0x9c88d68, _M_node =
0x9c88464}, __result=
      {_M_cur = 0xbf5dd088, _M_first = 0x0, _M_last = 0x0, _M_node =
0xbf5dd3c0})
    at /usr/lib/gcc/i486-slackware-linux/4.3.3/../../../../include/c++/4.3.3/
bits/stl_algobase.h:340
340               for(_Distance __n = __last - __first; __n > 0; --__n)

Though the actual crash point varies.

Thanks for any help.

B2003

I am rather sure that it is nothing to do with malloc or stl. It is
your code which has corrupted the memory. Use valgrind to find use of
uninitialized memory. Try analyzing your code with gdb also.

Regards,
Jyoti
 
B

boltar2003

Last time I had a stack problem, I just wrote a very small
assembler routine, to return the value of the stackpointer.
That value, as the stack became full , moved to zero.
So if your system works likewise, use such a routine to
quit at the right moment, while there is still some left.

Is there a way of doing that in C rather than assembler? My x86 assembler
isn't great but I want the program to be portable anyway.

B2003
 
B

boltar2003

Yes it does, but as you see in the following, malloc does not return.
There is a SIGSEGV crash in malloc. This is usually not caused by=20
exhaustion of the heap, but by corruption of the internal heap=20
administration. This could be due to running out of stack space.

Thats what I thought , but is there a simple way to check if the stack
is about to be used up?

I just tried this simple test program and the exact same thing happens:

$ cat t.c
int main()
{
func();
}
$ cc t.c
$ a.out
Segmentation fault (core dumped)

So clearly running out of stack space causes a SIGSEGV but short of
trapping the signal which is usually a waste of time as the program is
hopelessly corrupted by that point I'm wondering if theres another
way of finding out.

B2003
 
B

boltar2003

On Wed, 28 Apr 2010 09:21:56 +0000 (UTC)
$ cat t.c
int main()
{
func();
}

Sorry , cut and paste went wrong, that obviously should have been:

int main()
{
main();
}

B2003
 
Ö

Öö Tiib

On Wed, 28 Apr 2010 09:21:56 +0000 (UTC)

Sorry , cut and paste went wrong, that obviously should have been:

int main()
{
        main();

}

That is illegal to call main.
 
Ö

Öö Tiib

Is there a way of doing that in C rather than assembler? My x86 assembler
isn't great but I want the program to be portable anyway.

There are no way to do it in C because stack and its location, size
and direction are platform specific. There may be platform specific
libraries that have functions to do something in C. If there are none
then you may have to write it (or parts of it) in assember.

If you have implementation that should be portable and that depends on
properties of stack then you end up having that functionality
differently implemented for each plaform used. So you should perhaps
enwrap it behind common interface to keep your code readable.
 
B

boltar2003

That is illegal to call main.

I don't think it is, but it doesn't matter because this crashes too:

$ cat t.c
void func()
{
func();
}


int main()
{
func();
}
$ cc t.c
$ a.out
Segmentation fault (core dumped)
 
Ö

Öö Tiib

This crashes too:

$ cat t.c
void func()
{
        func();

}

int main()
{
        func();}

$ cc t.c
$ a.out
Segmentation fault (core dumped)

Yes. Like i said in other thread you have to do some undefined by
standard things that are usually defined by platform or implementation
documentation. Microsoft for example throws seh (microsoft term)
exceptions and for restoring the damaged stack there is some sort of:

int _resetstkoflw();

I do not use such techniques, instead i avoid deep recursion. To avoid
deep recursion i avoid deep trees.
 
J

James Kanze

On Apr 28, 12:17 pm, (e-mail address removed) wrote:
There are no way to do it in C because stack and its location,
size and direction are platform specific. There may be
platform specific libraries that have functions to do
something in C. If there are none then you may have to write
it (or parts of it) in assember.

It's normally no problem to get the address of the stack in C or
C++; just take the address of a local variable. (This isn't
guaranteed by the standard, of course, which doesn't even
guarantee that there is a stack, per se.) What that address
means, and what information you can deduce from it, is very
implementation specific, but for a given platform, you can often
determine something. (I've written stack walkback routines for
a number of platforms in C++. The code for one platform doesn't
work on other platforms, but it's still C++.)
If you have implementation that should be portable and that
depends on properties of stack then you end up having that
functionality differently implemented for each plaform used.
So you should perhaps enwrap it behind common interface to
keep your code readable.

Yes. This is the usual solution.
 
J

James Kanze

[...]
GCC/G++/GLIBC has this built-in now:

G++ has had it for some time now, I think. But I had originally
implemented the code for VC++ and Sun CC, and I'm not sure that
g++ supported it when I originally wrote the code. Were I doing
it today, I'd certainly use the g++ function for the g++
versions of the code.
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top