Need help tracking down a SegFault

I need help finding the source of a SegFault. I believe that I have the
search narrowed down to a single line of code. Here’s the build and run
output:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules
battle.cpp: In member function ‘SDL_Surface* Battle::drawString(int,
int, std::string)’:
battle.cpp:109: warning: missing initializer for member
’SDL_Color::unused’
g++ -W -Wall sdl-config --cflags -c character.cpp
g++ -W -Wall sdl-config --cflags -c ally.cpp
g++ -W -Wall sdl-config --cflags -c main.cpp
g++ -o main battle.o character.o ally.o main.o sdl-config --libs
-lSDL_image -lSDL_gfx -lSDL_ttf -lz
Line is 65; i = 0
Segmentation fault
Here’s the offending function:

23	bool Battle::initialize()
24	{
25	   if (SDL_Init(SDL_INIT_VIDEO) != 0)
26	   {
27	      printf("Unable to initialize SDL:  %s\n", SDL_GetError());
28	      return false;
29	   }
30	   atexit(SDL_Quit);
31	   
32	   if( TTF_Init() == -1 ) 
33	   { 
34	      printf("Could not intialize the font:  %s\n",

SDL_GetError());
35 return false;
36 }
37 font = TTF_OpenFont( “lazy.ttf”, 18 );

38	   if( font == NULL ) 
39	   {
40	      printf("Error loading font:  %s\n", SDL_GetError());
41	      return false;
42	   }
43	   SDL_WM_SetCaption( "OurRPG - Battle Screen", NULL );
44	   screen =  SDL_SetVideoMode(1000, 675, 16, SDL_DOUBLEBUF |

SDL_HWSURFACE);
45 if (screen == NULL)
46 {
47 printf(“Unable to set video mode: %s\n”, SDL_GetError());
48 return false;
49 }

50	   for (int i = 0; i < 4; i++)
51	   {
52	      status[i] = NULL;
53	      party[i].setX(600);
54	      party[i].setY(i * 100);
55	      image[i] = party[i].getImage();
56	if (image[i] == NULL) printf("It's NULL!!!\n");
57	printf ("Line is %d; i = %i\n", __LINE__, i);
58	      colorkey = SDL_MapRGB(image[i]->format, 0, 255, 0);
59	printf ("Line is %d; i = %i\n", __LINE__, i);
60	      SDL_SetColorKey(image[i], SDL_SRCCOLORKEY, colorkey);
61	      
62	printf ("Line is %d; i = %i\n", __LINE__, i);
63	      src[i].x = 0;
64	printf ("Line is %d; i = %i\n", __LINE__, i);
65	      src[i].y = 0;
66	printf ("Line is %d; i = %i\n", __LINE__, i);
67	      src[i].w = image[i]->w;
68	printf ("Line is %d; i = %i\n", __LINE__, i);
69	      src[i].h = image[i]->h;
70	printf ("Line is %d; i = %i\n", __LINE__, i);
71	      
72	      dest[i].x = 600;
73	      dest[i].y = i * 100;
74	      dest[i].w = src[i].w;
75	      dest[i].h = src[i].h;
76	   }
77	printf ("Line is %d; i = %i\n", __LINE__, i);
   
78	   drawLines();
79	   drawStats();
   
80	   return true;
   
81	}

As you can see, the printf on 65 is firing, so image[i] is not NULL.
The problem seems to be with the colorkey line. Is there anything wrong
with how I’ve written this line? Please help!

Some additional info: Here’s what gdb says:

michael at camille ourrpg $ gdb main
GNU gdb 6.7.1
Copyright © 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…
(no debugging symbols found)
Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb) r
Starting program: /home/michael/ourrpg/main
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread 0x4000 (LWP 14191)]
Line is 65; i = 0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4000 (LWP 14191)]
0xb7f5b752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0xb7f5b752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
#1 0x080498f9 in Battle::initialize ()
#2 0x0804aee1 in main ()
(gdb) quit
The program is running. Exit anyway? (y or n) y

And valgrind too:

michael at camille ourrpg $ valgrind ./main
==14210== Memcheck, a memory error detector.
==14210== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14210== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14210== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14210== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14210== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14210== For more details, rerun with: -v
==14210==
==14210== Syscall param write(buf) points to uninitialised byte(s)
==14210== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14210== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14210== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14210== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14210== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14210==
==14210== Conditional jump or move depends on uninitialised value(s)
==14210== at 0x80498A0: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
Line is 65; i = 0
==14210==
==14210== Use of uninitialised value of size 4
==14210== at 0x80498D6: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
==14210==
==14210== Invalid read of size 4
==14210== at 0x407F752: SDL_MapRGB (in /usr/lib/libSDL-1.2.so.0.11.0)
==14210== by 0x80498F8: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
==14210== Address 0x0 is not stack’d, malloc’d or (recently) free’d
==14210==
==14210== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 37 from
1)
==14210== malloc/free: in use at exit: 75,377 bytes in 476 blocks.
==14210== malloc/free: 4,930 allocs, 4,454 frees, 1,735,303 bytes
allocated.
==14210== For counts of detected errors, rerun with: -v
==14210== searching for pointers to 476 not-freed blocks.
==14210== checked 898,684 bytes.
==14210==
==14210== LEAK SUMMARY:
==14210== definitely lost: 10 bytes in 2 blocks.
==14210== possibly lost: 187 bytes in 8 blocks.
==14210== still reachable: 75,180 bytes in 466 blocks.
==14210== suppressed: 0 bytes in 0 blocks.
==14210== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

I don’t completely understand how to interpret valgrind’s or gdb’s
output, so if there is something useful there, please tell me…On Sun, 2008-02-24 at 10:54 -0600, Michael Sullivan wrote:

I need help finding the source of a SegFault. I believe that I have the
search narrowed down to a single line of code. Here’s the build and run
output:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules
battle.cpp: In member function ‘SDL_Surface* Battle::drawString(int,
int, std::string)’:
battle.cpp:109: warning: missing initializer for member
’SDL_Color::unused’
g++ -W -Wall sdl-config --cflags -c character.cpp
g++ -W -Wall sdl-config --cflags -c ally.cpp
g++ -W -Wall sdl-config --cflags -c main.cpp
g++ -o main battle.o character.o ally.o main.o sdl-config --libs
-lSDL_image -lSDL_gfx -lSDL_ttf -lz
Line is 65; i = 0
Segmentation fault
Here’s the offending function:

23	bool Battle::initialize()
24	{
25	   if (SDL_Init(SDL_INIT_VIDEO) != 0)
26	   {
27	      printf("Unable to initialize SDL:  %s\n", SDL_GetError());
28	      return false;
29	   }
30	   atexit(SDL_Quit);
31	   
32	   if( TTF_Init() == -1 ) 
33	   { 
34	      printf("Could not intialize the font:  %s\n",

SDL_GetError());
35 return false;
36 }
37 font = TTF_OpenFont( “lazy.ttf”, 18 );

38	   if( font == NULL ) 
39	   {
40	      printf("Error loading font:  %s\n", SDL_GetError());
41	      return false;
42	   }
43	   SDL_WM_SetCaption( "OurRPG - Battle Screen", NULL );
44	   screen =  SDL_SetVideoMode(1000, 675, 16, SDL_DOUBLEBUF |

SDL_HWSURFACE);
45 if (screen == NULL)
46 {
47 printf(“Unable to set video mode: %s\n”, SDL_GetError());
48 return false;
49 }

50	   for (int i = 0; i < 4; i++)
51	   {
52	      status[i] = NULL;
53	      party[i].setX(600);
54	      party[i].setY(i * 100);
55	      image[i] = party[i].getImage();
56	if (image[i] == NULL) printf("It's NULL!!!\n");
57	printf ("Line is %d; i = %i\n", __LINE__, i);
58	      colorkey = SDL_MapRGB(image[i]->format, 0, 255, 0);
59	printf ("Line is %d; i = %i\n", __LINE__, i);
60	      SDL_SetColorKey(image[i], SDL_SRCCOLORKEY, colorkey);
61	      
62	printf ("Line is %d; i = %i\n", __LINE__, i);
63	      src[i].x = 0;
64	printf ("Line is %d; i = %i\n", __LINE__, i);
65	      src[i].y = 0;
66	printf ("Line is %d; i = %i\n", __LINE__, i);
67	      src[i].w = image[i]->w;
68	printf ("Line is %d; i = %i\n", __LINE__, i);
69	      src[i].h = image[i]->h;
70	printf ("Line is %d; i = %i\n", __LINE__, i);
71	      
72	      dest[i].x = 600;
73	      dest[i].y = i * 100;
74	      dest[i].w = src[i].w;
75	      dest[i].h = src[i].h;
76	   }
77	printf ("Line is %d; i = %i\n", __LINE__, i);
   
78	   drawLines();
79	   drawStats();
   
80	   return true;
   
81	}

As you can see, the printf on 65 is firing, so image[i] is not NULL.
The problem seems to be with the colorkey line. Is there anything wrong
with how I’ve written this line? Please help!

[…]

Compile the code with the -g option, and make sure your build scripts
aren’t stripping the debug info. That should get some more sensible
info out of gdb and Valgrind.

Also, compile with -O0 or possibly -O1. Modern compilers mess around
quite a bit with the code at higher optimization levels, so the code
you’re trying to debug may not even exist in the form you’d expect.

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Sunday 24 February 2008, Michael Sullivan wrote:

I need help finding the source of a SegFault. I believe that I have
the search narrowed down to a single line of code. Here’s the build
and run output:

Michael Sullivan skrev:

michael at camille ourrpg $ valgrind ./main
==14210== Memcheck, a memory error detector.
==14210== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14210== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14210== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14210== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14210== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14210== For more details, rerun with: -v
==14210==
==14210== Syscall param write(buf) points to uninitialised byte(s)
==14210== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14210== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14210== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14210== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14210== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14210==
==14210== Conditional jump or move depends on uninitialised value(s)
==14210== at 0x80498A0: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
Line is 65; i = 0
==14210==
==14210== Use of uninitialised value of size 4
==14210== at 0x80498D6: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
==14210==
==14210== Invalid read of size 4
==14210== at 0x407F752: SDL_MapRGB (in /usr/lib/libSDL-1.2.so.0.11.0)
==14210== by 0x80498F8: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
==14210== Address 0x0 is not stack’d, malloc’d or (recently) free’d
==14210==
==14210== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 37 from
1)
==14210== malloc/free: in use at exit: 75,377 bytes in 476 blocks.
==14210== malloc/free: 4,930 allocs, 4,454 frees, 1,735,303 bytes
allocated.
==14210== For counts of detected errors, rerun with: -v
==14210== searching for pointers to 476 not-freed blocks.
==14210== checked 898,684 bytes.
==14210==
==14210== LEAK SUMMARY:
==14210== definitely lost: 10 bytes in 2 blocks.
==14210== possibly lost: 187 bytes in 8 blocks.
==14210== still reachable: 75,180 bytes in 466 blocks.
==14210== suppressed: 0 bytes in 0 blocks.
==14210== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

I don’t completely understand how to interpret valgrind’s or gdb’s
output, so if there is something useful there, please tell me…

You should build the program with debug symbols so that GDB and Valgrind
shows filename:linenumber information.

Michael Sullivan skrev:

michael at camille ourrpg $ valgrind ./main
==14210== Memcheck, a memory error detector.
==14210== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14210== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14210== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14210== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14210== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14210== For more details, rerun with: -v
==14210==
==14210== Syscall param write(buf) points to uninitialised byte(s)
==14210== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14210== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14210== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14210== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14210== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14210==
==14210== Conditional jump or move depends on uninitialised value(s)
==14210== at 0x80498A0: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
Line is 65; i = 0
==14210==
==14210== Use of uninitialised value of size 4
==14210== at 0x80498D6: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
==14210==
==14210== Invalid read of size 4
==14210== at 0x407F752: SDL_MapRGB (in /usr/lib/libSDL-1.2.so.0.11.0)
==14210== by 0x80498F8: Battle::initialize()
(in /home/michael/ourrpg/main)
==14210== by 0x804AEE0: main (in /home/michael/ourrpg/main)
==14210== Address 0x0 is not stack’d, malloc’d or (recently) free’d
==14210==
==14210== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 37 from
1)
==14210== malloc/free: in use at exit: 75,377 bytes in 476 blocks.
==14210== malloc/free: 4,930 allocs, 4,454 frees, 1,735,303 bytes
allocated.
==14210== For counts of detected errors, rerun with: -v
==14210== searching for pointers to 476 not-freed blocks.
==14210== checked 898,684 bytes.
==14210==
==14210== LEAK SUMMARY:
==14210== definitely lost: 10 bytes in 2 blocks.
==14210== possibly lost: 187 bytes in 8 blocks.
==14210== still reachable: 75,180 bytes in 466 blocks.
==14210== suppressed: 0 bytes in 0 blocks.
==14210== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

I don’t completely understand how to interpret valgrind’s or gdb’s
output, so if there is something useful there, please tell me…

You should build the program with debug symbols so that GDB and Valgrind
shows filename:linenumber information.


Sorry, I thought the debugging info was already in there. Here’s the
new gdb output:

michael at camille ourrpg $ gdb main
GNU gdb 6.7.1
Copyright © 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…
Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb) r
Starting program: /home/michael/ourrpg/main
[Thread debugging using libthread_db enabled]
[New Thread 0x4000 (LWP 14482)]
Line is 65; i = 0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4000 (LWP 14482)]
0xb7e9a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0xb7e9a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
#1 0x080498f9 in Battle::initialize (this=0xbfa23454) at battle.cpp:66
#2 0x0804aee1 in main () at main.cpp:7
(gdb) quit
The program is running. Exit anyway? (y or n) y

And valgrind:

michael at camille ourrpg $ valgrind ./main
==14488== Memcheck, a memory error detector.
==14488== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14488== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14488== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14488== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14488== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14488== For more details, rerun with: -v
==14488==
==14488== Syscall param write(buf) points to uninitialised byte(s)
==14488== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14488== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14488== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14488== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14488== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14488==
==14488== Conditional jump or move depends on uninitialised value(s)
==14488== at 0x80498A0: Battle::initialize() (battle.cpp:64)
==14488== by 0x804AEE0: main (main.cpp:7)
Line is 65; i = 0
==14488==
==14488== Use of uninitialised value of size 4
==14488== at 0x80498D6: Battle::initialize() (battle.cpp:66)
==14488== by 0x804AEE0: main (main.cpp:7)
==14488==
==14488== Invalid read of size 4
==14488== at 0x407F752: SDL_MapRGB (in /usr/lib/libSDL-1.2.so.0.11.0)
==14488== by 0x80498F8: Battle::initialize() (battle.cpp:66)
==14488== by 0x804AEE0: main (main.cpp:7)
==14488== Address 0x0 is not stack’d, malloc’d or (recently) free’d
==14488==
==14488== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 37 from
1)
==14488== malloc/free: in use at exit: 75,377 bytes in 476 blocks.
==14488== malloc/free: 4,931 allocs, 4,455 frees, 1,735,407 bytes
allocated.
==14488== For counts of detected errors, rerun with: -v
==14488== searching for pointers to 476 not-freed blocks.
==14488== checked 898,684 bytes.
==14488==
==14488== LEAK SUMMARY:
==14488== definitely lost: 10 bytes in 2 blocks.
==14488== possibly lost: 187 bytes in 8 blocks.
==14488== still reachable: 75,180 bytes in 466 blocks.
==14488== suppressed: 0 bytes in 0 blocks.
==14488== Rerun with --leak-check=full to see details of leaked memory.
Segmentation faultOn Sun, 2008-02-24 at 18:26 +0100, Erik wrote:

Michael Sullivan skrev:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules
Fix those warnings first and see if it helps.

Michael Sullivan skrev:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules
Fix those warnings first and see if it helps.


What does that even mean; "name lookup of ‘i’ changed?On Sun, 2008-02-24 at 19:20 +0100, Erik wrote:

Michael Sullivan skrev:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules
Fix those warnings first and see if it helps.


michael at camille ourrpg $ make
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘SDL_Surface* Battle::drawString(int,
int, std::string)’:
battle.cpp:108: warning: missing initializer for member
’SDL_Color::unused’
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c character.cpp
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c ally.cpp
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c main.cpp
g++ -o main battle.o character.o ally.o main.o sdl-config --libs
-lSDL_image -lSDL_gfx -lSDL_ttf -lz
michael at camille ourrpg $ gdb main
GNU gdb 6.7.1
Copyright © 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…
Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb) r
Starting program: /home/michael/ourrpg/main
[Thread debugging using libthread_db enabled]
[New Thread 0x4000 (LWP 14641)]
Line is 65; i = 0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4000 (LWP 14641)]
0xb7f1a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0xb7f1a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
#1 0x080496d6 in Battle::initialize (this=0xbfca96d4) at battle.cpp:66
#2 0x0804b087 in main () at main.cpp:7
(gdb) quit
The program is running. Exit anyway? (y or n) y
michael at camille ourrpg $ valgrind ./main
==14644== Memcheck, a memory error detector.
==14644== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14644== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14644== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14644== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14644== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14644== For more details, rerun with: -v
==14644==
==14644== Syscall param write(buf) points to uninitialised byte(s)
==14644== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14644== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14644== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14644== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14644== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14644==
==14644== Conditional jump or move depends on uninitialised value(s)
==14644== at 0x8049683: Battle::initialize() (battle.cpp:64)
==14644== by 0x804B086: main (main.cpp:7)
Line is 65; i = 0
==14644==
==14644== Use of uninitialised value of size 4
==14644== at 0x80496CB: Battle::initialize() (battle.cpp:66)
==14644== by 0x804B086: main (main.cpp:7)
==14644==
==14644== Invalid read of size 4
==14644== at 0x407F752: SDL_MapRGB (in /usr/lib/libSDL-1.2.so.0.11.0)
==14644== by 0x80496D5: Battle::initialize() (battle.cpp:66)
==14644== by 0x804B086: main (main.cpp:7)
==14644== Address 0x0 is not stack’d, malloc’d or (recently) free’d
==14644==
==14644== ERROR SUMMARY: 5 errors from 4 contexts (suppressed: 37 from
1)
==14644== malloc/free: in use at exit: 75,377 bytes in 476 blocks.
==14644== malloc/free: 4,930 allocs, 4,454 frees, 1,735,303 bytes
allocated.
==14644== For counts of detected errors, rerun with: -v
==14644== searching for pointers to 476 not-freed blocks.
==14644== checked 898,700 bytes.
==14644==
==14644== LEAK SUMMARY:
==14644== definitely lost: 10 bytes in 2 blocks.
==14644== possibly lost: 187 bytes in 8 blocks.
==14644== still reachable: 75,180 bytes in 466 blocks.
==14644== suppressed: 0 bytes in 0 blocks.
==14644== Rerun with --leak-check=full to see details of leaked memory.
Segmentation faultOn Sun, 2008-02-24 at 19:20 +0100, Erik wrote:

Michael Sullivan skrev:> On Sun, 2008-02-24 at 19:20 +0100, Erik wrote:

Michael Sullivan skrev:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules

Fix those warnings first and see if it helps.


michael at camille ourrpg $ make
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘SDL_Surface* Battle::drawString(int,
int, std::string)’:
battle.cpp:108: warning: missing initializer for member
’SDL_Color::unused’
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c character.cpp
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c ally.cpp
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c main.cpp
g++ -o main battle.o character.o ally.o main.o sdl-config --libs
-lSDL_image -lSDL_gfx -lSDL_ttf -lz
michael at camille ourrpg $ gdb main
GNU gdb 6.7.1
Copyright © 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…
Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb) r
Starting program: /home/michael/ourrpg/main
[Thread debugging using libthread_db enabled]
[New Thread 0x4000 (LWP 14641)]
Line is 65; i = 0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4000 (LWP 14641)]
0xb7f1a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0xb7f1a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
#1 0x080496d6 in Battle::initialize (this=0xbfca96d4) at battle.cpp:66
#2 0x0804b087 in main () at main.cpp:7
(gdb) quit
The program is running. Exit anyway? (y or n) y
michael at camille ourrpg $ valgrind ./main
==14644== Memcheck, a memory error detector.
==14644== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14644== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14644== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14644== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14644== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14644== For more details, rerun with: -v
==14644==
==14644== Syscall param write(buf) points to uninitialised byte(s)
==14644== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14644== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14644== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14644== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14644== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14644==
==14644== Conditional jump or move depends on uninitialised value(s)
==14644== at 0x8049683: Battle::initialize() (battle.cpp:64)
==14644== by 0x804B086: main (main.cpp:7)

This is the first error that Valgrind finds in your code, so that is
where you should start fixing. (Ignore anything that comes after that.)
I do not know if -O1 is good to use when debugging, -O0 may be safer, so
it does not show the wrong line numbers somewhere.

Michael Sullivan skrev:> On Sun, 2008-02-24 at 19:20 +0100, Erik wrote:

Michael Sullivan skrev:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules

Fix those warnings first and see if it helps.

What does that even mean; "name lookup of ‘i’ changed?

It means that some old unofficial versions of C++ may interpret your
code differently than it should be interpreted according to the
standard. Just make sure that all variables go out of scope as soon as
they are not used any more. Whenever possible, variables should be
declared inside the statement where they are used:
for (uint32_t i …
instead of:
uint32_t i;
for (i = …

and:
if (T * const p = …
instead of:
T * const p = …
if § …

If you can not declare the variable inside a statement like that, create
the smallest possible scope for it with {}:
{
uint32_t i;
for (i = …

// use i after the loop
} // make sure that i goes out of scope immediately when it is no
longer used

Michael Sullivan skrev:

Michael Sullivan skrev:

michael at camille ourrpg $ make && ./main
g++ -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘bool Battle::initialize()’:
battle.cpp:85: warning: name lookup of ‘i’ changed
battle.cpp:11: warning: matches this ‘i’ under ISO standard rules
battle.cpp:58: warning: matches this ‘i’ under old rules

Fix those warnings first and see if it helps.


michael at camille ourrpg $ make
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘SDL_Surface* Battle::drawString(int,
int, std::string)’:
battle.cpp:108: warning: missing initializer for member
’SDL_Color::unused’
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c character.cpp
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c ally.cpp
g++ -O1 -g -ggdb -W -Wall sdl-config --cflags -c main.cpp
g++ -o main battle.o character.o ally.o main.o sdl-config --libs
-lSDL_image -lSDL_gfx -lSDL_ttf -lz
michael at camille ourrpg $ gdb main
GNU gdb 6.7.1
Copyright © 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…
Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb) r
Starting program: /home/michael/ourrpg/main
[Thread debugging using libthread_db enabled]
[New Thread 0x4000 (LWP 14641)]
Line is 65; i = 0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4000 (LWP 14641)]
0xb7f1a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0xb7f1a752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
#1 0x080496d6 in Battle::initialize (this=0xbfca96d4) at battle.cpp:66
#2 0x0804b087 in main () at main.cpp:7
(gdb) quit
The program is running. Exit anyway? (y or n) y
michael at camille ourrpg $ valgrind ./main
==14644== Memcheck, a memory error detector.
==14644== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14644== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14644== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14644== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14644== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14644== For more details, rerun with: -v
==14644==
==14644== Syscall param write(buf) points to uninitialised byte(s)
==14644== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14644== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14644== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14644== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14644== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
==14644==
==14644== Conditional jump or move depends on uninitialised value(s)
==14644== at 0x8049683: Battle::initialize() (battle.cpp:64)
==14644== by 0x804B086: main (main.cpp:7)

This is the first error that Valgrind finds in your code, so that is
where you should start fixing. (Ignore anything that comes after that.)
I do not know if -O1 is good to use when debugging, -O0 may be safer, so
it does not show the wrong line numbers somewhere.


Line 64? It’s only purpose is to check to see if image[i] is null; it
has no meaning beyond that, and can be taken out at any time…

Here’s updated data:

michael at camille ourrpg $ make
g++ -O0 -g -ggdb -W -Wall sdl-config --cflags -c battle.cpp
battle.cpp: In member function ‘SDL_Surface* Battle::drawString(int,
int, std::string)’:
battle.cpp:108: warning: missing initializer for member
’SDL_Color::unused’
g++ -O0 -g -ggdb -W -Wall sdl-config --cflags -c character.cpp
g++ -O0 -g -ggdb -W -Wall sdl-config --cflags -c ally.cpp
g++ -O0 -g -ggdb -W -Wall sdl-config --cflags -c main.cpp
g++ -o main battle.o character.o ally.o main.o sdl-config --libs
-lSDL_image -lSDL_gfx -lSDL_ttf -lz
michael at camille ourrpg $ gdb main
GNU gdb 6.7.1
Copyright © 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…
Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb) r
Starting program: /home/michael/ourrpg/main
[Thread debugging using libthread_db enabled]
[New Thread 0x4000 (LWP 14915)]
Line is 65; i = 0

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4000 (LWP 14915)]
0xb7f30752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
(gdb) backtrace
#0 0xb7f30752 in SDL_MapRGB () from /usr/lib/libSDL-1.2.so.0
#1 0x080498ac in Battle::initialize (this=0xbff20144) at battle.cpp:66
#2 0x0804ae95 in main () at main.cpp:7
(gdb) q
The program is running. Exit anyway? (y or n) y
michael at camille ourrpg $ valgrind ./main
==14918== Memcheck, a memory error detector.
==14918== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et
al.
==14918== Using LibVEX rev 1732, a library for dynamic binary
translation.
==14918== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==14918== Using valgrind-3.2.3, a dynamic binary instrumentation
framework.
==14918== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et
al.
==14918== For more details, rerun with: -v
==14918==
==14918== Syscall param write(buf) points to uninitialised byte(s)
==14918== at 0x40DD69E: write (in /lib/libpthread-0.10.so)
==14918== by 0x458DE7D: (within /usr/lib/libX11.so.6.2.0)
==14918== Address 0x465897B is 19 bytes inside a block of size 16,384
alloc’d
==14918== at 0x4021ABE: calloc
(in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==14918== by 0x45731B3: XOpenDisplay (in /usr/lib/libX11.so.6.2.0)
Line is 65; i = 0
==14918==
==14918== Use of uninitialised value of size 4
==14918== at 0x8049889: Battle::initialize() (battle.cpp:66)
==14918== by 0x804AE94: main (main.cpp:7)
==14918==
==14918== Invalid read of size 4
==14918== at 0x407F752: SDL_MapRGB (in /usr/lib/libSDL-1.2.so.0.11.0)
==14918== by 0x80498AB: Battle::initialize() (battle.cpp:66)
==14918== by 0x804AE94: main (main.cpp:7)
==14918== Address 0x0 is not stack’d, malloc’d or (recently) free’d
==14918==
==14918== ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 37 from
1)
==14918== malloc/free: in use at exit: 75,377 bytes in 476 blocks.
==14918== malloc/free: 4,930 allocs, 4,454 frees, 1,735,303 bytes
allocated.
==14918== For counts of detected errors, rerun with: -v
==14918== searching for pointers to 476 not-freed blocks.
==14918== checked 898,684 bytes.
==14918==
==14918== LEAK SUMMARY:
==14918== definitely lost: 10 bytes in 2 blocks.
==14918== possibly lost: 187 bytes in 8 blocks.
==14918== still reachable: 75,180 bytes in 466 blocks.
==14918== suppressed: 0 bytes in 0 blocks.
==14918== Rerun with --leak-check=full to see details of leaked memory.
Segmentation faultOn Sun, 2008-02-24 at 19:56 +0100, Erik wrote:

On Sun, 2008-02-24 at 19:20 +0100, Erik wrote:

I need help finding the source of a SegFault. I believe that I have the
search narrowed down to a single line of code. Here’s the build and run
output:
[…]
Line is 65; i = 0
Segmentation fault
Here’s the offending function:
[…]
65 src[i].y = 0;

I suspect your line numbers are off. Line 65 could not produce that
debug message :slight_smile:

in gdb when your program crashes do an “up” until you are back in your
function and do “l” to list the code with line numbers.

As someone else noted, compiling with “-O0” might be a good idea.

On your deeper problem: you did not show where “src”, “image” or other
such varaibles are defined. I suspect you are writing to unallocated
memory.

Especially the line “image[i] = party[i].getImage();” – did you make
sure that your getImage() returns a pointer to newly allocated memory
each time?

CU,
SecOn Sun, Feb 24, 2008 at 10:54 -0600, Michael Sullivan wrote:

    Since compiler users outnumber compiler writers 1000:1, if it's
    possible to save a compiler user 1 hour, it's worth 1000 hours
    of the compiler writer's time.