Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is not stack'd, malloc'd or (recently) free'd, when all the variables is used

When I call this function:

int within(struct key *node, int *value) {                      
  int length = len(node);                                       
  if ((value <= node[length-1].data) && (value >= node[0].data)) // Problematic line
    return 0;                                                   
  else if (value > node[length-1].data)                         
    return 1;                                                   
  else if (value < node[0].data)                                
    return -1;                                                  
}                                                               

Valgrind raises this error message:

Address 0x51f60a0 is not stack'd, malloc'd or (recently) free'd

value and node variables have correct values. All the variables is used. What is wrong with memory management there? Please, tell me, if the snippet doesn't clear the situation.

like image 927
I159 Avatar asked May 21 '14 18:05

I159


3 Answers

The message Address 0x51f60a0 is not stack'd, malloc'd or (recently) free is usually only a part of a larger Valgrind error message.

These Valgrind error messages usually looks something like this:

Invalid read of size 4
   at 0x40F6BBCC: (within /usr/lib/libpng.so.2.1.0.9)
   by 0x40F6B804: (within /usr/lib/libpng.so.2.1.0.9)
   by 0x40B07FF4: read_png_image__FP8QImageIO (kernel/qpngio.cpp:326)
   by 0x40AC751B: QImageIO::read() (kernel/qimage.cpp:3621)
   Address 0xBFFFF0E0 is not stack'd, malloc'd or free'd

or

Invalid read of size 8
   at 0x40060E: free_adj_list (main.c:9)
   by 0x400844: main (main.c:65)
 Address 0x4c1d170 is 16 bytes inside a block of size 24 free'd
   at 0x4A04D72: free (vg_replace_malloc.c:325)
   by 0x400609: free_adj_list (main.c:8)
   by 0x400844: main (main.c:65)

How to read these error messages

The first part of the message indicates what went wrong ("Invalid read of size 4" would mean that you tried to read from a memory address which you should not access), followed by the backtrace where the error occurred.

The backtrace is followed by details about the memory address which you tried to access. Valgrind makes a guess here as to what you might have meant, by looking whether the address is:

  • just outside of a a part of memory that you do have access to (so your program did a buffer overrun). Example message would be Address 0x1002772ac is 4 bytes after a block of size 12 alloc'd
  • inside a block of memory that was free'd before (so your program used memory after it was freed); example: Address 0x4c1d170 is 16 bytes inside a block of size 24 free'd

And these messages are then followed by a second backtrace which indicates where you allocated or freed the memory mentioned.

But the message Address 0x51f60a0 is not stack'd, malloc'd or (recently) free'd means that Valgrind couldn't guess what you meant to do. You tried to access memory at 0x51f60a0 but that address was not recently freed, and is not near any other part of memory you have allocated. So you can be reasonably sure that the error in this case is neither a buffer overrun nor is it a use-after-free error.

How to debug errors like this

So we can assume that 0x51f60a0 is some more or less "random" memory address. I can think of mainly two possible causes for this:

  • the pointer you dereferenced contained some uninitialized value; in this case you should also get a Use of uninitialised value error message from Valgrind
  • you dereferenced a value that was not intended as a pointer at all - eg. the value might actually be the result of some unrelated calculation in your program, and somehow you wrote that value to the pointer that you used later

Apart from these, there is of course still the possibility that the error is in fact some buffer overrun or use-after-free but Valgrind failed to detect it.

How to debug this error in your program

I think one way to narrow down the problem would be to start the application in Valgrind with GDB to find out what memory access exactly causes the error (is node bad? Is node[length-1] bad? Is node[0] bad?). Then find out how the bad value came there in the first place.

like image 113
oliver Avatar answered Nov 17 '22 04:11

oliver


Your comparison(s) should be
*value <= node[length-1].data
not
value <= node[length-1].data

IOW, you're missing the asterisk before the value variable.

like image 39
KevinDTimm Avatar answered Nov 17 '22 03:11

KevinDTimm


What caused my problem of "not stack'd, malloc'd or (recently) free'd". I hope this is useful to someone directed here by a search engine like me.

In my case, I allocated a heap array p of size 585. But then I tried to access p in the index range of 733~1300. And valgrind just showed that message.

like image 24
duleshi Avatar answered Nov 17 '22 05:11

duleshi