C Dynamic Memory Debugging with Valgrind

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello I'm dr. Brian Fraser and in this video I'm going to show how to use the tool Val grind to check the memory accesses for a C or C++ program under Linux so to begin with I've written a program that tries to commit as many terrible actions with dynamic memory as possible I've loaded it up in Eclipse and I put together a make file so this will build the project and all of my terrible tests here as well I just want to show you what happens I make there's my command that actually performs my build I named my file bad underscore memory C and so I run bad memory it runs like that and that is exactly what it should do it looks fine there's no problems all of the output is exactly as I had expected from just writing the code or at least what I might have expected if I was not trying to inject certain errors into my system now what I could do is I can come back into my code I can see here in my main I'm going to run these four different test functions each of which is set up to demonstrate a separate type of failure so let me go up to the top I can look at test 1 and I could try and figure out what's going to be wrong with it and I can look through and figure out ok maybe this is the problem maybe that's the problem but as it stands memory bugs are very hard to find chances are your entire system just starts to do crazy things your middle of a string just changes a value randomly some variable that you've got just changes a value randomly and you're not quite sure why so let's bring in Val grind and figure out what's going on here so Val grind is a tool or in fact it's a suite of debugging and profiling tools that allow you to check your code in a number of powerful ways the default tool and perhaps one of the best is the mem Scheck feature and this will find a lot of different memory access problems and the way it does this is it runs your code inside of a virtual machine it then instruments all of the memory accesses and so forth that you're performing and it double checks to make sure that all of your pointer accesses are valid now let's start off with seeing how you'd install it I already have I'll grind installed but if you have sudo access to your machine you don't have a Val grind installed that's going to be sudo apt-get on a Debian system such as Ubuntu install well grind and then hit enter type in your password and it'll go through and try and install it so we see here that I've already got to install that wants to do a cleanup but that's fine okay so now that I've got it the next thing to do is to set up your project to build correctly you want to make sure that you build here's my make file with the - G option which sets up debugging information and that gives valgrind enough information to instrument your system correctly and give you meaningful results when it finds errors I'm going to put the vet - G in now you'll also note that I have both W all and W error turned on this is what I normally code with so that I let the compiler tells me tell me as much as possible about the things I'm doing wrong and as we saw when I build I'll go out here and make it finds nothing now I did spend a bit of time confusing the compiler in at least one case so that it couldn't find an error I was committing but all the same my code build without any warnings or any errors plus I also have the c99 turned on so that I can use variable declarations inside for loops so let's go back and look at the code so rather than me trying to walk through this and you know painstakingly I try to identify my memory accesses the kind of things I'd be looking for or every time I call malloc I call free well right off the bat here I not calling free anywhere but that didn't cause any failures but let's see what would happen over time as I get a big memory leak off that so I'm going to use Val grind to try and trace this through now let's just start off with Val grind let's go look like Val grind bad memory is my funk or my program and so when I run this it starts up the virtual machine it runs everything through and all of these lines that start off with equal equal and then a number that is a message from Val grind to me describing something that it had found of interest so if I scroll back up we can see the very top it's got some basic you know this is just hey Val grinds starting to run the number incidentally is the process ID or the pit of the current process it's working on it can trace Forks you get a number of options to work on that so if you're trying to debug a program that is forking separate processes it will also help you out then we can see then as when it starts here it starts to tell me different errors so for example invalid write of size 4 so I'm writing 4 bytes to an invalid location it'll tell me exactly where so on bad memory dot see at line 11 so it's telling me line 11 here I'm trying to write 4 bytes of data at an invalid location they'll give me more than that as well and tell me the actual address that I'm trying to write to and it's inside of a block of size 3 that was allocated mmm so I can start to trace that through we can see here that I've got a lot of errors though and at the very bottom it gives me a nice display of some summary I'm going to go back into my code and I'm going to comment out everything except the first function we're going to walk this through one at a time so I'm going to make press up to get Val grind and so let's start at the top so that invalid access so it's telling me I'm trying to use some memory I don't have permission to access well I can have a look at my code so what am i doing I'm going to create a constant for a number Heights so 3 I want to create three Heights I'm Alex some space for the number that I want here and then I'm going to set up a loop well the first thing I might do is check my loop size so I'm going to loop from I equals 0 I less than 3 I plus plus that looks pretty good my access here I access the memory as an array that's fine pointers and arrays there's a duality and see so that looks good as well and then I assign a value to I squared no problems then finally I print it out that should be fine as well so we get a problem here Val grinds not lying to us what's going on well I have allocated 3 but three what turns out to be three bites if I want to look at what the help is for mallik so let's do that a man Malek allocates and deallocate or put me allocates and free dynamic memory here these all are our functions and malloc function that allocates size bytes so I need to give it the number of bytes I want I said three I don't want three bytes I want three times the size in it now I could say three times so I could say well on my system is going to be four bytes that would work but if I switch systems that might that's not portable so a better idea is size of int that's one step better because now it's going to scale based on the size and end but even better is if I say star height Heights this is the variable I'm creating and so star Heights says whatever it points to now you might think well I'm going to dereference a null pointer here but sighs it isn't actually going to run it at run time and dereference a null pointer the compiler subs in how big size of ends up being so size of whatever height points to while I'm pointing to intz so it's going to give me the size of an int this is fantastic because if I come down here and I say well I want to switch this to a long my code automatically updates this line of code I can say well let's make this char I don't need to change anything else on this line of code because this is automatically scaling let's go back to the int so I'm going to quit that lets make and then I'm going to revalue and okay so we got rid of all those pesky errors at the top about saying we have the wrong amount of space allocated however down here we can say heap in use at exit so the heap is the dynamic allocation for malloc and we had 12 bytes in one block so we had one thing we may looked that was unfree at the end I tell us a leak summary and it knows that we leaked 12 bytes of memory it's got some other things that maybe it couldn't trace through quite so well and I'll give you indirect impossible leaks but here this is a definite leak so we're only ever calling this function Melik is called here so I need to call free I need to free at once so I'm going to free Heights put it here build clear just to make the screen cleaner and then rerun this we see here now there are no errors in the middle no bytes in use at the end no leaks are possible and we're good zero errors and from zero context that looks pretty good I want to show one last error here and in fact this will generate a runtime error normally I'm going to move my free inside of my loop so I'm going to try and free this multiple times so of course you cannot free one block of dynamic memory more than once so if I try if I just run this I said I get a normal error here from C++ or C partly so error in bad memory double free or corruption which is to say that either I've already freed this memory or I somehow clobbered it with some other pointer access it's not quite sure of course here I am multi freeing it so I can put that back down here as it should be oops just to clean up the code as we go ok so now if I go back to Val grind we're good lice beautiful figured out I'm going to change this now to test to go up and have a look at what test to does let's roll that up just for fun so we can have a quick look at test two but let's imagine that we wrote this code we tested it carefully and we couldn't find the bugs so I'm going to make this I got a Val grind again I'll see what happens ah invalid write of size 8 hey we remember what this looked like let's figure out what's going on line 26 of my code I tried to write eight bytes and it tells me inside of a block of size 40 freed hmm let's look at 26 what's 26 doing well 26 is trying to write it's only 8 bytes my waits is a long long so it's trying to write one long long into their eight bytes sounds good but and it tells me it was freed so inside of a block of size 40 that was freed so I had already called free on this so this is a very common bug of you freed some port some region of memory and then you begin to access it these are quite dastardly because you're never quite sure who owns that memory after you freed it so here's the problem of course I did all my work and then I freed the memory and then I began to use the memory at gain so I'm going to press alt down and re line this up so that I use the memory and then I free it make a gain and regrind it no errors here and we have one allocation it tells us one free we did 40 bytes of allocated memory but there are no problems with it we are good to go ok let's move on to test 3 I'll rebuild let's grind it definitely lost we got 40 bytes lost in one block let's check out why hmm well we call malloc and we call free so there's probably something more see if it gives us any of other information we can incidentally run with a leak check full option and it will then give us a much more information about where blocks were allocate and so forth let's just try that see if it gives us any help rerun I think I might have to move that up front see that helps there we go gives us a little bit more information and that says this was allocated by test three on line twenty thirty two so I can look at line 32 it'll tell me exactly where I lost the memory I say well hang on that doesn't look right I'm putting it here but if you look in the middle we have here this if height is null well height shouldn't the heights shouldn't be no because I've allocated it up here but of course the issue here is that a good double I've got single equal instead of double equal a very common bug in this case my compiler would have told me about it but I managed to suppress that by putting an extra set of brackets around it so this is a good way to screw up your program by just doing the the most simple-minded thing to make it compile so in this case the issue is I'm going to change my pointer to null by this line of code and then I call malloc which of course over writes it so what I might really want to do is change this to double equal to four let's let's walk this through slowly let's get rid of those double brackets there now when I call make it actually gives me a error because it's suggest putting the brackets around it because this looks suspicious and in fact this would just be a warning normally but I've told it that I want to treat all warnings as errors so now it gives me a bit more of stronger warning so I'm going to say double equals and now it should be fine because now I am no longer reallocating the space of course inside my loop I didn't really want to do that to begin with so I'd probably just comment that out it's not the right kind of thing to do okay and now let's go check out test number four I know test number four calls another function so I got that here so test number four is simply going to print out whatever get string gives us so you get string creates a an array size 100 and it says hello world I'm going to create a pointer from this array now this step is kind of useless we'll see what that does in a minute and then I'm going to return the pointer so that looks pretty good I'm not even using dynamic memory here let's see if I anything happened so if I just run this bad memory way that doesn't look quite quite right supposed to say hello world but it came out of a garbage in fact it when I run it a bunch of different times it comes up garbage every different time so that's kind of funny so that's your hint that something is wrong code that shouldn't be giving me different answers is let's try and trace that through now I could think about this and try and reason through it let's see what valgrind is going to do for me it's around bad memory through valgrind and up here it says conditional jump or move depends on uninitialized values so that seems kind of weird now this is inside of the F printf which isn't called from printf which is called from test for now anytime that you've got a statement like this it's sort of a red flag yeah sure it looks like printf is doing the bad thing you I think there's a bug in C Lib which there could be but here it's not so likely we can see here line 49 of course is my printf statement here there's something going awry it's trying to read from uninitialized memory so it's probably moving data into to print up to the screen we can see it does this all the way down here the i/o file and so forth prams - right points - uninitialized bytes so it's done a fair number of things it looks like a lot of different bugs this actually stems from just one issue and the issue is that I am beginning to use the stack so this is just running off the stack and I'm passing in an address off the stack now really what I want to do here as I tried to start with is I want to return message but let's get out of this GCC is smart enough to tell me hey you are returning your function is returning the address of a local variable now this again is a warning it's just a warning but that's really you know your house is on fire it's just a warning because this is going to sit on the stack and when I leave the function it gets popped off the stack and so this pointer becomes invalid after I leave this process this function so then print out a I get a pointer to memory it looks good but of course it's on this stack and I don't have access anymore so that's what we're getting here Val grind can help us trace that through so after I've gone through all and fix all these bugs my program should then run without any errors or any warnings or should compile without any errors or warnings and Val grind should also come up and show me that everything is fine alright thank you for watching
Info
Channel: Brian Fraser
Views: 97,892
Rating: 4.9662209 out of 5
Keywords: Valgrind, C (Programming Language), C Dynamic Memory Allocation, Software (Industry)
Id: bb1bTJtgXrI
Channel Id: undefined
Length: 17min 50sec (1070 seconds)
Published: Thu Feb 05 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.