Thread: Can someone remind me how to tell gcc not to 0 initialise everything in debug mode

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Can someone remind me how to tell gcc not to 0 initialise everything in debug mode

    Tried googling it but google didn't seem to understand what I was looking for, brought up everything but, I need to stop it happening so I can track down variables that need to be initialised

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    I am not aware that gcc zero-initializes everything in "debug mode". I assume you are talking about local variables since globals and statics are always zero-initialized if not explicitly initialized.

    You could try looking here:
    Debugging Options (Using the GNU Compiler Collection (GCC))

    EDIT: I just tried the following:
    Code:
    #include <stdio.h>
     
    void f()
    {
        int a, b, c, d;
        if (a || b || c || d) printf("f: non-zero detected\n");
        else                  printf("f: all zeroes\n");
    }
     
    int main()
    {
        int a, b, c, d;    
        if (a || b || c || d) printf("main: non-zero detected\n");
        else                  printf("main: all zeroes\n");
        return 0;
    }
    Output:
    $ gcc zeroed.c -g
    $ ./a.out
    main: non-zero detected
    Last edited by john.c; 03-31-2022 at 05:30 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by john.c View Post
    I am not aware that gcc zero-initializes everything in "debug mode". I assume you are talking about local variables since globals and statics are always zero-initialized if not explicitly initialized.

    You could try looking here:
    Debugging Options (Using the GNU Compiler Collection (GCC))

    EDIT: I just tried the following:
    Code:
    #include <stdio.h>
     
    void f()
    {
        int a, b, c, d;
        if (a || b || c || d) printf("f: non-zero detected\n");
        else                  printf("f: all zeroes\n");
    }
     
    int main()
    {
        int a, b, c, d;    
        if (a || b || c || d) printf("main: non-zero detected\n");
        else                  printf("main: all zeroes\n");
        return 0;
    }
    Output:
    $ gcc zeroed.c -g
    $ ./a.out
    main: non-zero detected
    I appreciate the link but I already looked there, that's what I meant by everything but what I was looking for, and yeah that non-zero situation is definitly what I'm looking for in debug mode yet when I run the code in release vs debug I never get the bug showing in debug (which is obviously annoying, how am I to catch a segfault that only happens in release mode, there won't be enough information for me to identify what function/code to look through). True the uninitialised data I'm looking for is usually 0'd even in release mode but occasionally I get a crash and I can only attribute it to uninitialised data, if only I knew where to look I could fix it.

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,112
    Quote Originally Posted by awsdert View Post
    Tried googling it but google didn't seem to understand what I was looking for, brought up everything but, I need to stop it happening so I can track down variables that need to be initialized
    If you are referring to global variables, then "-fno-zero-initialized-in-bss" may be what you are looking for. See this page for more information.

    Local variables are never initialized to zero by default.

    Also, please view a complete list of gcc options.
    Last edited by rstanley; 03-31-2022 at 06:18 PM.

  5. #5
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Try running with valgrind.

    This brings back up what I was typing in a different thread:

    I pity the next person who comes along, and should the debugger stops at "ENUM( Type, E_BUFF_TYPE_INDICE, GL_ELEMENT_ARRAY_BUFFER );" is left scratching their head. Only to find out that "GfxBufTypeEnums[]" has been declared too small.

    However, it more than likely that the debugger won't stop, and your code will just trash a random memory location somewhere, giving them an almost unsolvable bug that will haunt their nightmares.
    In this case, that next person is might be you.

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    Try running with valgrind.

    This brings back up what I was typing in a different thread:



    In this case, that next person is might be you.
    Well that's not possible, the enums have counts built into them, I use those counts when declaring the array size so the compiler is able to catch it before it can reach production stage

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by rstanley View Post
    If you are referring to global variables, then "-fno-zero-initialized-in-bss" may be what you are looking for. See this page for more information.

    Local variables are never initialized to zero by default.

    Also, please view a complete list of gcc options.
    I don't think it's global variables that are the issue but I might as well try. Thanks for the link though, might prove more helpful than google in this case.

  8. #8
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,112
    Quote Originally Posted by awsdert View Post
    I don't think it's global variables that are the issue but I might as well try. Thanks for the link though, might prove more helpful than google in this case.
    After having a good strong cup of coffee this morning, I can't understand why you would want any and all variables NOT initialized to zero or some legitimate value! I can't see how variables picking up garbage values left in memory, would in any way help to debug any program!

    True the uninitialised data I'm looking for is usually 0'd even in release mode but occasionally I get a crash and I can only attribute it to uninitialised data, if only I knew where to look I could fix it.
    Seems simple. Go through your code and locate any local variables not initialized, and initialize them to zero or some legitimate value, and all pointers to NULL. As for malloc(), use memset(), or switch to calloc(). As for realloc() you would need to memset() the added memory. If that does not fix the problem, then you have more serious problems.

    Also, as soon as you free() and allocated memory, ALWAYS set the pointer to NULL, to avoid accidentally read or write the memory freed! I list all this not just to you but for the benefit of all readers of this thread.
    Last edited by rstanley; 04-01-2022 at 06:33 AM.

  9. #9
    Registered User
    Join Date
    Oct 2019
    Posts
    82
    Quote Originally Posted by rstanley View Post

    As for realloc() you would need to memset() the added memory.
    While this is possible, it might turn out more complicated than other cases which are simple enough.

    My guess is that one would have to keep track of the size of the currently allocated memory chunk then do something like:

    Code:
    memset(ptr + previous_size, 0, current_size - previous_size);

  10. #10
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,112
    Quote Originally Posted by ghoul View Post
    While this is possible, it might turn out more complicated than other cases which are simple enough.

    My guess is that one would have to keep track of the size of the currently allocated memory chunk then do something like:

    Code:
    memset(ptr + previous_size, 0, current_size - previous_size);
    Why do you think that was NOT what I was referring to??? I didn't think I had to give an explicit example to the OP!

  11. #11
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by rstanley View Post
    After having a good strong cup of coffee this morning, I can't understand why you would want any and all variables NOT initialized to zero or some legitimate value! I can't see how variables picking up garbage values left in memory, would in any way help to debug any program!


    Seems simple. Go through your code and locate any local variables not initialized, and initialize them to zero or some legitimate value, and all pointers to NULL. As for malloc(), use memset(), or switch to calloc(). As for realloc() you would need to memset() the added memory. If that does not fix the problem, then you have more serious problems.

    Also, as soon as you free() and allocated memory, ALWAYS set the pointer to NULL, to avoid accidentally read or write the memory freed! I list all this not just to you but for the benefit of all readers of this thread.
    There ARE legitimate reasons to avoid initialising all variables, namely speed, that initialisation takes an instruction, if your function can potentially exit before the variable is needed then that's wasted time which can add up, I make a point of avoiding initialising variables until I actually need them, yes it means the occasional bug creeps in when I forget it's not initialised but it's not often that happens.

  12. #12
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by rstanley View Post
    Why do you think that was NOT what I was referring to??? I didn't think I had to give an explicit example to the OP!
    Dude chill, the only place my code uses realloc is in buffers & there's dedicate handlers for adjusting the count of used elements, those handlers all defer to 1 handler that clears newly "allocated" elements before handing back to the caller so realloc is nowhere near the issue.

    It's definitely a variable in some function somewhere.

  13. #13
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,112
    Quote Originally Posted by awsdert View Post
    Dude chill, the only place my code uses realloc is in buffers & there's dedicate handlers for adjusting the count of used elements, those handlers all defer to 1 handler that clears newly "allocated" elements before handing back to the caller so realloc is nowhere near the issue.

    It's definitely a variable in some function somewhere.
    I was referring to a post by ghoul not you.

  14. #14
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,112
    Quote Originally Posted by awsdert View Post
    There ARE legitimate reasons to avoid initialising all variables, namely speed, that initialisation takes an instruction, if your function can potentially exit before the variable is needed then that's wasted time which can add up, I make a point of avoiding initialising variables until I actually need them, yes it means the occasional bug creeps in when I forget it's not initialised but it's not often that happens.
    When you say, "initialization", do you mean at compile time with a constant, or "assignment" later.
    Code:
    int main(void)
    {
       int a;         // Not initialized, assigned later
       int b = 0;     // Initialization to 0 at compile time
       ... 
       a = 0;         // Initial assignment, or re-assignment later
    
       return 0;
    }
    Depending on the context, the compiler might optimize the code by converting the "assignment", to an "initialization". Bottom line, actual 'Initialization" has no overhead at run-time. Look at the assembler code.

  15. #15
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by rstanley View Post
    When you say, "initialization", do you mean at compile time with a constant, or "assignment" later.
    Code:
    int main(void)
    {
       int a;         // Not initialized, assigned later
       int b = 0;     // Initialization to 0 at compile time
       ... 
       a = 0;         // Initial assignment, or re-assignment later
    
       return 0;
    }
    Depending on the context, the compiler might optimize the code by converting the "assignment", to an "initialization". Bottom line, actual 'Initialization" has no overhead at run-time. Look at the assembler code.
    I mean for reasons like this:
    Code:
    void* grow_buffer( struct buffer *B, uint total )
    {
    	void *array;
    	if ( B->total >= total )
    		return B->array;
    	array = realloc( B->array, B->Tsize * total );
    	if ( !array )
    		return NULL;
    	B->array = array;
    	B->total = total;
    	return array;
    }
    Notice how I don't need the array variable until after I checked I'm going to be using it, in C99 I could just declare it later but in C89 it must be at the top of the scope, since I like to keep my code as C89 compatabile as possible I have to decide what scopes I need to declare my variables in, I also don't like going to far in with the scope like say this:
    Code:
    void* grow_buffer( struct buffer *B, uint total )
    {
    	if ( B->total < total )
    	{
    		void *array = realloc( B->array, B->Tsize * total );
    		if ( !array )
    			return NULL;
    		B->array = array;
    		B->total = total;
    	}
    	return B->array;
    }
    If there's decent reason to use a sub scope then I avoid it & stick to the upper scope

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 04-24-2010, 01:35 PM
  2. Using the Debug mode ((F10) V.S 2005
    By csonx_p in forum Windows Programming
    Replies: 21
    Last Post: 06-17-2008, 05:06 PM
  3. Debug Mode
    By Coding in forum C# Programming
    Replies: 5
    Last Post: 02-14-2008, 03:00 PM
  4. Replies: 4
    Last Post: 09-16-2006, 07:11 PM
  5. Debug Mode Vs. Release Mode
    By incognito in forum Tech Board
    Replies: 5
    Last Post: 12-18-2003, 04:06 PM

Tags for this Thread