[opensuse-programming] Problem with large buffer on 10.2 when OK on 10.0
Hello, I am having problems running a program under Suse 10.2 that works on 10.0 when I increase the size of a buffer from 4MB to 8MB. The test program immediately segv faults on entry into the main function under 10.2 but runs fine on 10.0. I have cluster of nodes all identical with 2 x dual core AMD64, 8GB RAM. The Suse 10.0 machines have uname -a "Linux d801 2.6.13-15.13-smp #1 SMP Tue Nov 28 13:43:50 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux" Suse 10.2 machines have "Linux d803 2.6.18.2-34-default #1 SMP Mon Nov 27 11:46:27 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux" What I have tried: Program compiled on suse10.0 (gcc (GCC) 4.0.2 20050901 (prerelease) (SUSE Linux)) * Runs on 10.0 fine. * Crashes on 10.2 Program compiled on suse10.2 (gcc (GCC) 4.1.2 20061115 (prerelease) (SUSE Linux)) * Runs on 10.0 fine. * Crashes on 10.2 Sample gdb output (for 10.2 compile binary): --- (gdb) run Starting program: test-x86_64 Program received signal SIGSEGV, Segmentation fault. 0x0000000000400565 in main (argc=Cannot access memory at address 0x7fffc2f9e84c ) at test.c:23 --- where line 23 is first line of main function. Compile command for failed program: gcc -O0 -pedantic -Wall -ggdb -BUFFER_SIZE=2*1024*1024 -o test-x86_64 test.c Compile command for working program: gcc -O0 -pedantic -Wall -ggdb -DBUFFER_SIZE=1024*1024 -o test-x86_64 test.c Anyone have any ideas? --- test.c --- #include <stdio.h> #ifndef BUFFER_SIZE #define BUFFER_SIZE 16*1024 #endif void test_fill (int* a_buffer , int a_size) { int l_index = 0; for (l_index = 0; l_index < a_size; ++l_index) { *(a_buffer + l_index) = l_index % 1024; } } int main (int argc , char** argv) { int l_buffer[BUFFER_SIZE]; printf ("%s\n", "Hello World:"); /* Use array */ test_fill (&l_buffer[0], BUFFER_SIZE); printf ("%s\n", "Hello World again!"); return 0; } ___ ___________________________________________________________ The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Hi Justin It is just pure luck it works. When programming C/C++ you _MUST_ allocate memory before using it. Otherwhise you can declare it like 'int buffer[1024];' but it is much better using dynamic allocation with malloc(). -- MortenB |-----Original Message----- |From: justin finnerty [mailto:linuxchem@yahoo.com.au] |Sent: 7. mars 2007 11:51 |To: opensuse-programming@opensuse.org |Subject: [opensuse-programming] Problem with large buffer on |10.2 when OK on 10.0 | |Hello, | |I am having problems running a program under Suse 10.2 that |works on 10.0 when I increase the size of a |buffer from 4MB to 8MB. The test program immediately |segv faults on entry into the main function under 10.2 but |runs fine on 10.0. | |I have cluster of nodes all identical with 2 x dual core |AMD64, 8GB RAM. The Suse 10.0 machines have uname -a "Linux |d801 2.6.13-15.13-smp #1 SMP Tue Nov |28 13:43:50 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux" |Suse 10.2 machines have "Linux d803 |2.6.18.2-34-default #1 SMP Mon Nov 27 11:46:27 UTC |2006 x86_64 x86_64 x86_64 GNU/Linux" | |What I have tried: | |Program compiled on suse10.0 |(gcc (GCC) 4.0.2 20050901 (prerelease) (SUSE Linux)) |* Runs on 10.0 fine. |* Crashes on 10.2 | |Program compiled on suse10.2 |(gcc (GCC) 4.1.2 20061115 (prerelease) (SUSE Linux)) |* Runs on 10.0 fine. |* Crashes on 10.2 | |Sample gdb output (for 10.2 compile binary): |--- |(gdb) run |Starting program: test-x86_64 | |Program received signal SIGSEGV, Segmentation fault. |0x0000000000400565 in main (argc=Cannot access memory at |address 0x7fffc2f9e84c |) at test.c:23 |--- |where line 23 is first line of main function. | |Compile command for failed program: |gcc -O0 -pedantic -Wall -ggdb -BUFFER_SIZE=2*1024*1024 -o |test-x86_64 test.c | |Compile command for working program: |gcc -O0 -pedantic -Wall -ggdb -DBUFFER_SIZE=1024*1024 -o |test-x86_64 test.c | |Anyone have any ideas? | |--- |test.c |--- |#include <stdio.h> | |#ifndef BUFFER_SIZE |#define BUFFER_SIZE 16*1024 |#endif | |void |test_fill (int* a_buffer | , int a_size) |{ | int l_index = 0; | for (l_index = 0; | l_index < a_size; | ++l_index) | { | *(a_buffer + l_index) = l_index % 1024; | } |} | |int |main (int argc | , char** argv) |{ | int l_buffer[BUFFER_SIZE]; | printf ("%s\n", "Hello World:"); | /* Use array */ | test_fill (&l_buffer[0], BUFFER_SIZE); | printf ("%s\n", "Hello World again!"); | return 0; |} |___ | | | | |___________________________________________________________ |The all-new Yahoo! Mail goes wherever you go - free your email |address from your Internet provider. |http://uk.docs.yahoo.com/nowyoucan.html |--------------------------------------------------------------------- |To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org |For additional commands, e-mail: opensuse-programming+help@opensuse.org | | --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
justin finnerty wrote: My first guess is that you are running out of stack space when running on SuSE 10.2. In main you are allocating a local array, which will be done on the stack. For large data arrays you should use dynamically allocated memory that will come from the heap, and not the stack. Hope this helps, Burt
Anyone have any ideas?
--- test.c --- #include <stdio.h>
#ifndef BUFFER_SIZE #define BUFFER_SIZE 16*1024 #endif
void test_fill (int* a_buffer , int a_size) { int l_index = 0; for (l_index = 0; l_index < a_size; ++l_index) { *(a_buffer + l_index) = l_index % 1024; } }
int main (int argc , char** argv) { int l_buffer[BUFFER_SIZE]; printf ("%s\n", "Hello World:"); /* Use array */ test_fill (&l_buffer[0], BUFFER_SIZE); printf ("%s\n", "Hello World again!"); return 0; } ___
___________________________________________________________ The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
--------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
On Wed, 7 Mar 2007 10:51:08 +0000 (GMT) justin finnerty <linuxchem@yahoo.com.au> wrote:
#ifndef BUFFER_SIZE #define BUFFER_SIZE 16*1024 #endif
int main (int argc , char** argv) { int l_buffer[BUFFER_SIZE];
Just a couple of additional issues since this is a stack overflow problem. You've got a 16MB buffer size allocated in main(). You would be better off declaring the buffer as static: static int l_buffer[BUFFER_SIZE]; This way, l_buffer would be allocated at compile time not run time. Note that the storage for automatic variables allocated in main() persist for the duration of the program. As you found out, stack space can be limited, so if your program counts on unusually large stack requirements, it may not run on all Unix/Linux platforms. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Wednesday 07 March 2007 09:11, Jerry Feldman wrote:
On Wed, 7 Mar 2007 10:51:08 +0000 (GMT)
justin finnerty <linuxchem@yahoo.com.au> wrote:
#ifndef BUFFER_SIZE #define BUFFER_SIZE 16*1024 #endif
int main (int argc , char** argv) { int l_buffer[BUFFER_SIZE];
Just a couple of additional issues since this is a stack overflow problem. You've got a 16MB buffer size allocated in main(). You would be better off declaring the buffer as static:
As was already suggested.
static int l_buffer[BUFFER_SIZE];
This way, l_buffer would be allocated at compile time not run time.
The space required would be recorded in the object file, but unless there's an initializer present, the space implied by the declaration would not be occupied in the object file. The allocation would occur only when setting up the BSS area (uninitialized data) during execution (i.e., the exec(2) system call) of the program..
...
Randall Schulz --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
The space required would be recorded in the object file, but unless there's an initializer present, the space implied by the declaration would not be occupied in the object file. The allocation would occur only when setting up the BSS area (uninitialized data) during execution (i.e., the exec(2) system call) of the program. I didn't want to get too specific. Yes, it would go into the .bss
On Wed, 7 Mar 2007 10:16:17 -0800 Randall R Schulz <rschulz@sonic.net> wrote: section (uninitialized data). More specifically, the memory pages would not be created until written to. It used to be that when a program loads, its text, data (initialized), and bss (uninitialized) would be set up when a program is loaded, even in a virtual memory environment, but now only the necessary pages are loaded. (I'm generalizing a bit here). -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Wed, 7 Mar 2007 10:16:17 -0800 Randall R Schulz <rschulz@sonic.net> wrote:
As was already suggested. Not when I composed the message, but I sent it from the wrong address, and the other posts then preceded it. Isn't email a wonderful medium :-) -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Wednesday 07 March 2007 11:51, justin finnerty wrote:
Hello,
I am having problems running a program under Suse 10.2 that works on 10.0 when I increase the size of a buffer from 4MB to 8MB. The test program immediately segv faults on entry into the main function under 10.2 but runs fine on 10.0.
Stack space is limited to 8MB by default. This is by ulimit. You can set this for the current shell with ulimit -s 20000 for example, to increase the limit to 20000K. Or you can increase it globally by editing /etc/security/limits.conf But it is better to allocate on the heap, as others have pointed out --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
participants (6)
-
Anders Johansson
-
Burt Bicksler
-
Jerry Feldman
-
justin finnerty
-
Morten Bjørnsvik
-
Randall R Schulz