This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: segfault on memory intensive programs


--- Dave Korn <dave.korn@artimi.com> wrote:

> On 30 March 2006 14:34, Pete wrote:
> 
> > The executable is produced with:
> > 
> > $ make
> > g++ -W -Wall -O9 -funroll-loops -mtune=pentium4  
> -c
> > -o matrix_mult_r.o matrix_mult_r.cc
> 
>   Heh.
> 
> 
> matrix_mult_r.cc:5:19: Timer.h: No such file or
> directory
> matrix_mult_r.cc: In function `int main()':
> matrix_mult_r.cc:20: error: `Timer' undeclared
> (first use this function)
> matrix_mult_r.cc:20: error: (Each undeclared
> identifier is reported only once
> for each function it appears in.)
> matrix_mult_r.cc:20: error: expected `;' before
> "timer"
> matrix_mult_r.cc:21: error: `timer' undeclared
> (first use this function)

ok... ok... :)

Attaching the files to the email.  Hope attachments
are OK.

> However, it's straightforward enough.  The default
> thread stack is 1Mb (or
> is it 2, I can't remember off the top of my head). 
> Once your stack-based auto
> vars exceed the size of the stack, it go BOOOOOM!

But doesn't the implementation keep track of stack
allocations?  Why let the hardware report a SIGSEGV
rather than let libc report "Out of memory" and
killing the process?

>   Your problem can be fixed /either/ by making them
> of static storage duration
> (move them out of the function body OR add the
> 'static' qualifier depending on
> scoping considerations),

Trying to learn...   Is that because if I declare the
variables as static (or make them global), they're
placed in the "data segment" and the compiler
automatically allocates enough space for them?

> or by using the -Wl,--stack
> flag.  Correctly.  You
> told ld to provide an 8kB stack.  Try 80 meg
> instead, it works a lot beter!

Yes, that definitely did the trick.  Thanks!  I think
the FAQ should be expanded a bit on the subject (I'd
be willing to write and submit if there's noone
designated as FAQ maintainer).

One last issue.  I was replying to one of your earlier
emails about using GDB.  For some reason, no matter
what I do, GDB always segfaults when I run the program
under GDB.

For a nice small eigensystem (N=200, ITERATIONS=2000):

$ make
g++ -W -Wall -O9 -funroll-loops -mtune=pentium4 -g  
-c -o matrix_mult_r.o matrix_mult_r.cc
g++ -W -Wall -O9 -funroll-loops -mtune=pentium4 -g  
-c -o Timer.o Timer.cc
g++ -Wl,--heap,8192,--stack,83886080 -o
matrix_mult_r.exe *.o
$ gdb matrix_mult_r.exe

(gdb) break 1
Breakpoint 1 at 0x401220: file matrix_mult_r.cc, line
1.
(gdb) run

Breakpoint 1, main () at matrix_mult_r.cc:16
16      {
(gdb) n
0x004101f0 in _alloca ()
(gdb) n
Single stepping until exit from function _alloca,
which has no line number information.
0x004101f6 in probe ()
(gdb) n
Single stepping until exit from function probe,
which has no line number information.
0x0041020d in done ()
(gdb) n
Single stepping until exit from function done,
which has no line number information.
main () at matrix_mult_r.cc:16
16      {
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x610ae938 in pthread_key_create () from
/usr/bin/cygwin1.dll


I use GDB quite a bit, and would _really_ like to be
able to use in on Cygwin.  The problem isn't even with
my benchmarking code.  Even with a hello world
program:

#include <iostream>
using namespace std;

int main( void )
{
   cout << "hello world" << endl;

   return 0;
}

when compiled with:

$ g++ -g  foo.cc

produces a segfault under GDB:

$ gdb -quiet a.exe
(gdb) break 1
Breakpoint 1 at 0x401150: file foo.cc, line 1.
(gdb) run

Breakpoint 1, main () at foo.cc:6
6       {
(gdb) n
0x0040f400 in _alloca () at
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/iostream:77
77        static ios_base::Init __ioinit;
(gdb) n
main () at foo.cc:6
6       {
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x610ae938 in pthread_key_create () from
/usr/bin/cygwin1.dll

Also, I noticed from my benchmark code that GDB
reports that it's in libc (or whatever!) functions
like alloca().  Is there a way to surpress mention of
any stepping into functions that don't have debugging
information?

Thanks again,
Pete

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Attachment: Makefile
Description: 402397780-Makefile

#define  N           600   // The dimension of the matrices
#define  ITERATIONS 2000   // Number of times to perform multiplication.

#include "Timer.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void complain_and_die( void );
static int  getInt( const int low, const int high );
static void fill_matrix( int m[][N] );
static void matrix_multiplication( const int a[][N], const int b[][N], int result[][N] );



int main( void )
{
	// Set up the timer and start it ticking.
	Timer timer;
	timer.startTimer();

	// We multiply m1 and m2, and put the result in m3.
	int m1[N][N];
	int m2[N][N];
	int m3[N][N];

	// Seed the random number generator
	srand( time(NULL) );

	// Perform the multiplication ITERATIONS times.
	for ( int i = 0; i < ITERATIONS; ++i )
	{
		fill_matrix( m1 );
		fill_matrix( m2 );
		matrix_multiplication( m1, m2, m3 );
	}

	// Stop the timer and end the program.
	timer.endTimer();
	timer.printStats();
	return 0;
}



inline static void complain_and_die( void )
{
	fprintf( stderr, "I need the rank of the matrix\n" );
	exit(1);
}



inline static int getInt( const int low, const int high )
{
	return low + ( rand() % (high - low + 1) );
}



inline static void fill_matrix( int m[][N] )
{
	for ( int i = 0; i < N; ++i )
		for ( int j = 0; j < N; ++j )
			m[i][j] = getInt(0, 100);
}



inline static void matrix_multiplication( const int a[][N], const int b[][N], int result[][N] )
{
	for( int i = 0; i < N; ++i )
		for( int j = 0; j < 3; ++j )
			for( int k = 0; k < N ; ++k )
				result[i][j] = a[i][k] + b[k][j];
}
#include <iostream>
#include <iomanip>
#include "Timer.h"
using namespace std;



Timer::Timer()
{
}



Timer::~Timer()
{
}



void Timer::startTimer( void )
{
	gettimeofday(&t_start, NULL);
	this->start = t_start.tv_sec + t_start.tv_usec * SECONDS_PER_MICROSECOND;
}



void Timer::endTimer( void )
{
	gettimeofday(&t_end, NULL);
	this->end = t_end.tv_sec + t_end.tv_usec * SECONDS_PER_MICROSECOND;
}



double Timer::getTimeInSeconds( void )
{
	return this->end - this->start;
}



// In seconds since the epoch.
//
double Timer::getStartTime( void )
{
	return this->start;
}



// In seconds since the epoch.
//
double Timer::getEndTime( void )
{
	return this->end;
}



void Timer::printStats( void )
{
	streamsize prec = cout.precision();
	cout << setprecision(12) << endl << "Timing Stats:" << endl;
	// cout << "End:   " << this->end << " seconds" << endl;
	// cout << "Start: " << this->start << " seconds" << endl;
	cout << "Total: " << this->getTimeInSeconds() << " seconds" << endl;
	cout << setprecision(prec);   // be polite.
}
#ifndef TIMER_H
#define TIMER_H

#include <sys/time.h>
#define SECONDS_PER_MICROSECOND 1.0E-6L;

class Timer
{
	private:
		timeval t_start, t_end;
		double  start, end;

	public:
		Timer::Timer();
		Timer::~Timer();
		void   Timer::startTimer( void );
		void   Timer::endTimer( void );
		double Timer::getTimeInSeconds( void );
		double Timer::getStartTime( void );
		double Timer::getEndTime( void );
		void   Timer::printStats( void );
};

#endif

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]