Thread: Invalid read error

  1. #1
    Registered User
    Join Date
    Apr 2013
    Posts
    6

    Invalid read error

    Hi all,

    I am debugging a code I developed for quite some time now and I could use some suggestions about how to proceed further, as I have lost a lot of time already. There are no errors anymore, so I'm using valgrind to detect memory leaks. There are no memory leaks anymore, but valgrind continues to give me some concerning warnings.
    There are hundreds of these warnings, and all but two are the following: "Conditional jump or move depends on uninitialised value(s)". The other two are "Invalid read of size 8". The second warning is accompanied by "Address 0x59c3ce8 is 8 bytes after a block of size 112 alloc'd", from which I can deduce which variable is read erroniously. The variable is called "Groups" and it is a pointer to an array of structures which I defined myself. Valgrind gives also two lines in the code where the invalid read is to be found. The first is in the declaration of the concerning function (i.e. void function(...)) which I call in main() and which accepts Groups as an argument. The other is a line in function() which does not contain Groups.
    From previous experience I know that I should solve the invalid read errors first. The invalid read probably produces most of the other errors, if not all of them. However, after quite some time, I don't see any problem in the declaration, initialisation of Groups, neither in the reading of its elements. Does anybody have some ideas about how I should proceed next to discover more about the origin of the error?

    Thanks very much in advance,
    Giorgos

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You may want to start by posting the relevant code. Without seeing any code there isn't much we can say.

    Jim

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    I would try working on these "Conditional jump or move depends on uninitialised value(s)"; esp. since you could not find the cause of the other valgrind warnings.

    Note: I have never used valgrind.

    I would at least compile it again with full compiler warnings to see if you failed to initialize a variable.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Do you compile with debugging symbols (-g) and without optimisation?
    Don't you get line numbers with the "Conditional jump"-errors?
    How does the structure look like?

    There is also the option "--track-origin=yes" which should give you more information about the uninitialised values:
    Code:
    $ cat ./foo.c
    #include <stdlib.h>
    
    int main(void)
    {
        struct test { int a, b; };
        struct test *p = malloc(14 * sizeof(*p));
    
        p[15].a = 12;
    
        int x, y;
        if (x == 2)
            y = p[14].a;
        else
            y = p[15].a;
        return 0;
    }
    $ valgrind ./foo
    ==3993== Memcheck, a memory error detector
    ==3993== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==3993== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==3993== Command: ./foo
    ==3993== 
    ==3993== Invalid write of size 4
    ==3993==    at 0x8048404: main (foo.c:8)
    ==3993==  Address 0x41f20a0 is 8 bytes after a block of size 112 alloc'd
    ==3993==    at 0x402BABA: malloc (vg_replace_malloc.c:263)
    ==3993==    by 0x80483F8: main (foo.c:6)
    ==3993== 
    ==3993== Conditional jump or move depends on uninitialised value(s)
    ==3993==    at 0x804840F: main (foo.c:11)
    ==3993== 
    ==3993== Invalid read of size 4
    ==3993==    at 0x8048427: main (foo.c:14)
    ==3993==  Address 0x41f20a0 is 8 bytes after a block of size 112 alloc'd
    ==3993==    at 0x402BABA: malloc (vg_replace_malloc.c:263)
    ==3993==    by 0x80483F8: main (foo.c:6)
    ==3993== 
    ==3993== 
    ==3993== HEAP SUMMARY:
    ==3993==     in use at exit: 112 bytes in 1 blocks
    ==3993==   total heap usage: 1 allocs, 0 frees, 112 bytes allocated
    ==3993== 
    ==3993== LEAK SUMMARY:
    ==3993==    definitely lost: 112 bytes in 1 blocks
    ==3993==    indirectly lost: 0 bytes in 0 blocks
    ==3993==      possibly lost: 0 bytes in 0 blocks
    ==3993==    still reachable: 0 bytes in 0 blocks
    ==3993==         suppressed: 0 bytes in 0 blocks
    ==3993== Rerun with --leak-check=full to see details of leaked memory
    ==3993== 
    ==3993== For counts of detected and suppressed errors, rerun with: -v
    ==3993== Use --track-origins=yes to see where uninitialised values come from
    ==3993== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
    $ valgrind -q --track-origins=yes ./foo
    ==3994== Invalid write of size 4
    ==3994==    at 0x8048404: main (foo.c:8)
    ==3994==  Address 0x41f20a0 is 8 bytes after a block of size 112 alloc'd
    ==3994==    at 0x402BABA: malloc (vg_replace_malloc.c:263)
    ==3994==    by 0x80483F8: main (foo.c:6)
    ==3994== 
    ==3994== Conditional jump or move depends on uninitialised value(s)
    ==3994==    at 0x804840F: main (foo.c:11)
    ==3994==  Uninitialised value was created by a stack allocation
    ==3994==    at 0x80483EA: main (foo.c:4)
    ==3994== 
    ==3994== Invalid read of size 4
    ==3994==    at 0x8048427: main (foo.c:14)
    ==3994==  Address 0x41f20a0 is 8 bytes after a block of size 112 alloc'd
    ==3994==    at 0x402BABA: malloc (vg_replace_malloc.c:263)
    ==3994==    by 0x80483F8: main (foo.c:6)
    ==3994==
    Bye, Andreas

  5. #5
    Registered User
    Join Date
    Apr 2013
    Posts
    6
    Hi, thanks for the help AndiPersti. I found out in the meanwhile that the conditional jumps and the invalid reads are unrelated, so sorry for the fuzz. The conditional jumps I managed to solve now. However, I still don't see where the invalid reads are coming from.
    The errors refer to the line where BAE[i] is allocated in the func_Z() function. The errors are:
    Code:
    ==7407== Invalid read of size 8
    ==7407==    at 0x411851: func_Z (dcoeff.c:3)
    ==7407==    by 0x41482D: main (main.c:79)
    ==7407==  Address 0x59c3d80 is 0 bytes after a block of size 144 alloc'd
    ==7407==    at 0x4A06B0F: calloc (vg_replace_malloc.c:593)
    ==7407==    by 0x40EB1F: func_Z (dcoeff.c:43)
    ==7407==    by 0x41482D: main (main.c:79)
    ==7407== 
    ==7407== Invalid read of size 8
    ==7407==    at 0x411854: func_Z (dcoeff.c:3)
    ==7407==    by 0x41482D: main (main.c:79)
    ==7407==  Address 0x59c3d88 is 8 bytes after a block of size 144 alloc'd
    ==7407==    at 0x4A06B0F: calloc (vg_replace_malloc.c:593)
    ==7407==    by 0x40EB1F: func_Z (dcoeff.c:43)
    ==7407==    by 0x41482D: main (main.c:79)
    ==7407==
    Here's the relevant code:

    Header:
    Code:
     #ifndef HEADER_H
    #define HEADER_H
    
    #include <stdlib.h>
    #include ... (and so on)
    
    #define PI 3.141592653589793
    
    typedef double _Complex cplx;
    
    struct Point;
    
    typedef struct Point{
      double x;
      double y;
    } Point;
    
    struct Groups;
    
    ... (and so on)
    
    int *NumQ;
    
    Point defineVec(double, double);
    Point ... (and so on)
    
    void func_Z(int, Group *, int *, int *, double, PartBlockMatrix *);
    void ... (and so on)
    
    #endif
    main.c:

    Code:
    #include "EFIEsolver.h"
    
    int main(){
    
      int NumGroups = 2;
      Group *Groups = (Group *) calloc(NumGroups,sizeof(Group));
      int *d_flag = (int *) calloc(NumGroups*(NumGroups+1)/2,sizeof(int));
      int *M = (int *) calloc(NumGroups,sizeof(int));
      PartBlockMatrix *Z = (PartBlockMatrix *) calloc(NumGroups*NumGroups,sizeof(PartBlockMatrix));
      NumQ = (int *) calloc(NumGroups,sizeof(int));
      double k = 2.*PI;
    
      ... (here follows the initialisation of all variables)
    
      func_Z(NumGroups, Groups, d_flag, M, k, Z);
    
      ... (freeing allocated memory)
    
    }
    The function func_Z:

    Code:
    #include "EFIEsolver.h"
    
    void func_Z(int NumGroups, Group *Groups, int *d_flag, int *M, double k, PartBlockMatrix *Z){
    
    int i;
    cplx **BAE, **HE2C;
    ... (and so on)
    
    BAE = (cplx **) calloc(NumGroups,sizeof(cplx *));
    HE2C = (cplx **) calloc(NumGroups,sizeof(cplx *));
    for(i=0;i<NumGroups;i++){
      BAE[i] = (cplx *) calloc(2*NumQ[i]+1,sizeof(cplx));
      HE2C[i] = (cplx *) calloc(2*NumQ[i]+1,sizeof(cplx));
    }
    ... (and so on)
    
    }
    Any help is welcome!

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Code:
    ==7407== Invalid read of size 8
    ==7407==    at 0x411851: func_Z (dcoeff.c:3)
    ==7407==    by 0x41482D: main (main.c:79)
    ==7407==  Address 0x59c3d80 is 0 bytes after a block of size 144 alloc'd
    ==7407==    at 0x4A06B0F: calloc (vg_replace_malloc.c:593)
    ==7407==    by 0x40EB1F: func_Z (dcoeff.c:43)
    ==7407==    by 0x41482D: main (main.c:79)
    This error message says that the invalid read happened at line 3 of dcoeff.c.
    So what's that line? Is it the function header?

    Bye, Andreas

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    Code:
    ==7407== Invalid read of size 8
    ==7407==    at 0x411851: func_Z (dcoeff.c:3)
    ==7407==    by 0x41482D: main (main.c:79)
    ==7407==  Address 0x59c3d80 is 0 bytes after a block of size 144 alloc'd
    ==7407==    at 0x4A06B0F: calloc (vg_replace_malloc.c:593)
    ==7407==    by 0x40EB1F: func_Z (dcoeff.c:43)
    ==7407==    by 0x41482D: main (main.c:79)
    It's really strange that the apparent "use" has such a low line number in the same file as the place where it is allocated.

    Especially since line 3 appears to be this
    void func_Z(int NumGroups, Group *Groups, int *d_flag, int *M, double k, PartBlockMatrix *Z)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    6
    The invalid read happens in the header, indeed. I've had similar errors before, and it took me days to figure out what it was. Unfortunately, I don't remember how I solved it, so I hoped that someone would have had a similar experience... Could it be that valgrind is not able to find the real problem in this case?

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Are you defining _Complex somewhere or is it supplied by the Compiler?

    Code:
    typedef double _Complex cplx;
    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  10. #10
    Registered User
    Join Date
    Apr 2013
    Posts
    6
    The keyword _Complex is supported by the C99 standard. I compile by adding it in my CMakeLists.txt as below. This shouldn't be a problem as I have worked previously with similar headers.

    Code:
    set(CMAKE_C_FLAGS "-std=c99 -Wall")

  11. #11
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Code:
    typedef double _Complex cplx;
    FYI: All the quick Googling GCC examples show it this way(_Complex before double/float); if it fixes it, it might be a compiler bug or user error.
    I have no idea what the standard says.

    Code:
    typedef _Complex double cplx;
    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  12. #12
    Registered User
    Join Date
    Apr 2013
    Posts
    6
    Thanks for the suggestions Tim S., but I found the error in the meanwhile.
    Following on the initialisation, a complicated structure of multiple nested for-loops is used. There I made an error of the following kind:

    Code:
    int i,j,k; cplx **BAE, **HE2C; ... (and so on)  
    BAE = (cplx **) calloc(NumGroups,sizeof(cplx *)); 
    HE2C = (cplx **) calloc(NumGroups,sizeof(cplx *)); 
    for(i=0;i<NumGroups;i++){  
        BAE[i] = (cplx *) calloc(2*NumQ[i]+1,sizeof(cplx));   
        HE2C[i] = (cplx *) calloc(2*NumQ[i]+1,sizeof(cplx)); 
    }...
    
    for(i=0;i<NumGroups;i++){
      for(j = 0;j<(2*NumQ[i]+1);j++){
        ...
      }
      ...
      for(k = 0;k<(2*NumQ[i]+1);k++){
        ... *= BAE[i][j];
      }
    }
    So as I was expecting, valgrind could not identify the error correctly in this case. Thanks for all suggestions!
    Last edited by Salem; 04-30-2013 at 10:48 PM. Reason: reformatted

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    But that IS an error.

    You're accessing BAE[i][j], but from the previous loop, j is now one past the end of the array.

    If the for k loop were inside the for j loop, there wouldn't be a memory access issue, because all the i, j subscripts would be valid.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Apr 2013
    Posts
    6
    Of course, I made an error, no discussion about that. My point was that valgrind should point to the line where the invalid read happens, not to the header of the function in which it happens or to the initialisation of the variable.

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    I've no idea what you're talking about, mostly because any sense of file structure (which you keep claiming is important) is totally lost in your posts.

    If you want to put code in header files, that's your problem.

    Neither the compiler or valgrind will give a damn whether you do or not. Each logical source line has an associated filename:line which is used to report diagnostics.
    It matters not one jot whether code came from a source file, or was #included along the way.

    Now that you know what the problem is, it shouldn't be too hard for you to rig up a test case in a few lines (and a few files) which demonstrates whatever it is you're complaining about.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Valgrind - Invalid read of size 1
    By Castelmagno in forum C Programming
    Replies: 7
    Last Post: 02-29-2012, 03:19 PM
  2. Valgrind Invalid Read/Write In C Program
    By Alex Richman in forum C Programming
    Replies: 2
    Last Post: 10-02-2011, 03:15 PM
  3. error: invalid conversion from 'int' to 'int*'
    By csharp100 in forum C++ Programming
    Replies: 4
    Last Post: 02-22-2011, 07:56 AM
  4. Invalid Read from Valgrind
    By jduro in forum C Programming
    Replies: 1
    Last Post: 10-05-2010, 11:28 AM
  5. read() returns invalid file descriptor ???
    By hoho in forum C Programming
    Replies: 4
    Last Post: 08-04-2006, 10:54 AM