Finding Memory leaks in C with Visual Studio 2013 - c

I am using Visual Studio 2013, and taking a course in C programming and we started talking about memory bugs detaction, in particular memory leaks, and how to detect them using Valgrind on Linux.
I want to know if there is a way to detect such memory leaks using VS 2013. I tried searching online but it just leads to lots of articles and blogs and msdn posts and blogs with lots of words like dump files, and analizing them, etc which weird because:
1) It sounds so complex, convoluted and unintuitive it is actually hard to comprehend it.
2) The main reason this is weird is due to the fact that VS is the most advanced IDE around and Microsoft spends so much money on in, yet from what I have read it seems that there is no simple way to use VS to detect memory leaks - certainly no way that's as simple as Valgrind where I only have to compile the program and run the command
valgrind -leaks-check=yes ProgramName
and it simply prints to me all location it thinks there is a memory leak and describes the error (like not freeing memory after allocating it with malloc hence having "dead" memory after the program finishes, or accessing memory that's out of the array bounds)
So my question is how to use VS 2013 in order to achieve the same results and to find out First in high level if there are memory leaks in the program, and second - to detect in a simple manner where those leaks are- preferably without involving dump files (not that I know how to use them anyway in VS).

The answer I offer cannot be perfect as exhaustively explaining ALL features VS2013 etc. offer to find C/C++ heap hickups could be a book well sold. And not a very thin one for that matter.
First, things I will NOT cover:
sal.h - Semantic annotations (which are also used by MS tools, if provided).
Not EVERY _Crt* function available. Only a few to give the idea.
Additional steps an application designer might to add to their design for a "production quality" code base.
Having said that, here a piece of annotated code containing various bugs. Each bug is annotated with how it was possible to detect it by means of what VS2013 has to offer. Either at run time or at compile time or with static code analysis.
The compile time error sections are placed in comments, btw.
#include "stdafx.h"
#include <crtdbg.h>
#include <malloc.h>
#include <cstdint>
#include <cstdlib>
// This small helper class shows the _Crt functions (some of them)
// and keeps the other code less cluttered.
// Note: This is NOT what you should do in production code,
// as all those _Crt functions disappear in a release build,
// but this class does not disappear...
class HeapNeutralSection
{
_CrtMemState m_start;
public:
HeapNeutralSection()
{
_CrtMemCheckpoint(&m_start);
}
~HeapNeutralSection()
{
_CrtMemState now;
_CrtMemState delta;
_CrtMemCheckpoint(&now);
if (_CrtMemDifference(&delta, &m_start, &now))
{
// This code section is not heap neutral!
_CrtMemDumpStatistics(&delta);
_CrtDumpMemoryLeaks();
_ASSERTE(false);
}
}
};
static void DoubleAllocationBug()
{
{
HeapNeutralSection hns;
uint32_t *rogue = (uint32_t*)malloc(sizeof(uint32_t));
if (NULL != rogue)
{
*rogue = 42; // Static Analysis without the NULL check: Dereferencing null pointer.
}
rogue = (uint32_t*)malloc(sizeof(uint32_t));
free(rogue);
// detected in destructor of HeapNeutralSection.
}
}
static void UninitializedPointerAccessBug()
{
// uint32_t *rogue;
// *rogue = 42; // C4700: uninitialized local variable 'rogue' used.
}
static void LeakBug()
{
{
HeapNeutralSection hns;
uint32_t *rogue = (uint32_t*)malloc(sizeof(uint32_t));
if (NULL != rogue)
{
*rogue = 42; // Static Analysis without the NULL check: Dereferencing null pointer.
}
}
}
static void InvalidPointerBug()
{
// Not sure if the C-compiler also finds this... one more reason to program C with C++ compiler ;)
// uint32_t *rogue = 234; // C2440: 'initalizing': cannot convert from 'int' to 'uint32_t *'
}
static void WriteOutOfRangeBug()
{
{
HeapNeutralSection hns;
uint32_t * rogue = (uint32_t*)malloc(sizeof(uint32_t));
if (NULL != rogue)
{
rogue[1] = 42; // Static analysis: warning C6200: Index '1' is out of valid index range '0' to '0' for non-stack buffer 'rogue'.
rogue[2] = 43; // Static analysis: warning C6200: Index '2' is out of valid index range '0' to '0' for non-stack buffer 'rogue'.
// warning C6386: Buffer overrun while writing to 'rogue': the writable size is '4' bytes, but '8' bytes might be written.
}
free(rogue); // We corrupted heap before. Next malloc/free should trigger a report.
/*
HEAP[ListAppend.exe]: Heap block at 0076CF20 modified at 0076CF50 past requested size of 28
ListAppend.exe has triggered a breakpoint.
*/
}
}
static void AccessAlreadyFreedMemoryBug()
{
{
HeapNeutralSection hns;
uint32_t * rogue = (uint32_t*)malloc(sizeof(uint32_t));
free(rogue);
*rogue = 42; // Static analysis: warning C6001: Using uninitialized memory 'rogue'.
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// checks heap integrity each time a heap allocation is caused. Slow but useful.
_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF);
AccessAlreadyFreedMemoryBug();
WriteOutOfRangeBug();
UninitializedPointerAccessBug();
DoubleAllocationBug();
// _CrtDumpMemoryLeaks();
return 0;
}
Last not least, on Windows CE and in the DDKs (maybe also in the platform SDKs), there used to be the 2 static code checkers "prefast" and "prefix". But maybe they are now outdated.
Additionally, there are MS research projects, going a step beyond sal.h, such as:
VCC, which help finding concurrency bugs etc.

Related

Why calling `free(malloc(8))`?

The Objective-C runtime's hashtable2.mm file contains the following code:
static void bootstrap (void) {
free(malloc(8));
prototypes = ALLOCTABLE (DEFAULT_ZONE);
prototypes->prototype = &protoPrototype;
prototypes->count = 1;
prototypes->nbBuckets = 1; /* has to be 1 so that the right bucket is 0 */
prototypes->buckets = ALLOCBUCKETS(DEFAULT_ZONE, 1);
prototypes->info = NULL;
((HashBucket *) prototypes->buckets)[0].count = 1;
((HashBucket *) prototypes->buckets)[0].elements.one = &protoPrototype;
};
Why does it allocate and release the 8-bytes space immediately?
Another source of confusion is this method from objc-os.h:
static __inline void *malloc_zone_malloc(malloc_zone_t z, size_t size) { return malloc(size); }
While it uses only one parameter, does the signature ask for two?
For the first question I can only assume. My bet it was done to avoid/reduce memory churn, or segment the memory for some other reason. You can briefly find where it's discussed in the Changelog of bmalloc (which is not quite relevant, but i could not find a better reference):
2017-06-02 Geoffrey Garen <ggaren#apple.com>
...
Updated for new APIs. Note that we cache one free chunk per page
class. This avoids churn in the large allocator when you
free(malloc(X))
It's unclear however, if the memory churn is caused by this technique or it was supposed to address it.
For the second question, Objective-C runtime used to work with "zones" in order to destroy all allocated variables by just destroying the said zone, but it proved being error prone and later it was agreed to not use it anymore. The API, however still uses it for historical reasons (backward compatibility, i assume), but says that zones are ignored:
Zones are ignored on iOS and 64-bit runtime on OS X. You should not use zones in current development.

why handle to an object frequently appears as pointer-to-pointer

What is the intention to set handle to an object as pointer-to pointer but not pointer? Like following code:
FT_Library library;
FT_Error error = FT_Init_FreeType( &library );
where
typedef struct FT_LibraryRec_ *FT_Library
so &library is a FT_LIBraryRec_ handle of type FT_LIBraryRec_**
It's a way to emulate pass by reference in C, which otherwise only have pass by value.
The 'C' library function FT_Init_FreeType has two outputs, the error code and/or the library handle (which is a pointer).
In C++ we'd more naturally either:
return an object which encapsulated the success or failure of the call and the library handle, or
return one output - the library handle, and throw an exception on failure.
C APIs are generally not implemented this way.
It is not unusual for a C Library function to return a success code, and to be passed the addresses of in/out variables to be conditionally mutated, as per the case above.
The approach hides implementation. It speeds up compilation of your code. It allows to upgrade data structures used by the library without breaking existing code that uses them. Finally, it makes sure the address of that object never changes, and that you don’t copy these objects.
Here’s how the version with a single pointer might be implemented:
struct FT_Struct
{
// Some fields/properties go here, e.g.
int field1;
char* field2;
}
FT_Error Init( FT_Struct* p )
{
p->field1 = 11;
p->field2 = malloc( 100 );
if( nullptr == p->field2 )
return E_OUTOFMEMORY;
return S_OK;
}
Or C++ equivalent, without any pointers:
class FT_Struct
{
int field1;
std::vector<char> field2;
public:
FT_Struct() :
field1( 11 )
{
field2.resize( 100 );
}
};
As a user of the library, you have to include struct/class FT_Struct definition. Libraries can be very complex so this will slow down compilation of your code.
If the library is dynamic i.e. *.dll on windows, *.so on linux or *.dylib on osx, you upgrade the library and if the new version changes memory layout of the struct/class, old applications will crash.
Because of the way C++ works, objects are passed by value, i.e. you normally expect them to be movable and copiable, which is not necessarily what library author wants to support.
Now consider the following function instead:
FT_Error Init( FT_Struct** pp )
{
try
{
*pp = new FT_Struct();
return S_OK;
}
catch( std::exception& ex )
{
return E_FAIL;
}
}
As a user of the library, you no longer need to know what’s inside FT_Struct or even what size it is. You don’t need to #include the implementation details, i.e. compilation will be faster.
This plays nicely with dynamic libraries, library author can change memory layout however they please, as long as the C API is stable, old apps will continue to work.
The API guarantees you won’t copy or move the values, you can’t copy structures of unknown lengths.

Can't detect C leaks in xcode 9 instruments

I'm trying to use instruments for the first time. So, I wrote a small C program to detect memory leaks in instruments.
Code:
#include <stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main()
{
int *temp = NULL;
temp = (int*)malloc(100*sizeof(int));
for (int i = 0; i<100; ++i) {
temp[i] = i;
}
printf("%d", *(temp+1));
printf("Hello ");
temp = NULL;
usleep(10000000);
printf("%d", *(temp+1));
}
When I use free(temp)
In the 1st pic, there are no leaks but in the below panel we can see the allocated details.
In the 2nd pic, there are no leaks but in the below panel we can see there are no details.
Why is that? Can anybody explain the output(top and below panels)?
Thank you!
Update:
You mean like this?
int main()
{
char **temp = NULL;
temp = (char**)malloc(100*sizeof(char*));
for (int i = 0; i<100; ++i) {
temp[i] = (char *)malloc(100*sizeof(char));
temp[i]=NULL;
usleep(2000000);
}
}
P.S I tagged C++ because I think the above code can be written in C++ also. Please remove the tag if I'm wrong.
There is no problem with your code. It creates a memory leak as you expected. The problem(actually its good) is with the Xcode.
Xcode optimises your code to remove all the memory leaks. Thats why instruments not showing any memory leaks.
To see your memory leaks, disable the optimisations in the Xcode.
Select None [-O0] to disable all the optimisations.
You use intstruments to profile the final production code. So, don't change the Release settings. You may forget to change it back and your program will not be optimised.
Instead edit the scheme of Profile from Release to Debug. Doing this you can always get optimised code for the Release.
1). Click on executable icon
2). Click on Edit Scheme.
3). Change the Build Configuration to Debug.
Now, whenever you profile your code, you will get all the errors as your code is not optimised.
To profile your release code, change it back to Release in the Build Configuration.

C program : function not being called from main

I am programming the Renesas RX63N microcontroller, in C using Renesas High-performance Embedded Workshop. The problem that I face is that a function, connectWiFi(), is not being executed from main. Following is the function's prototype:
typedef char String[5000];
void connectWiFi(String id, int auth, String psk);
The function body is this:
void connectWiFi(String id, int auth, String psk)
{
printf("log 0.1\n");
char cwTemp2[10];
String one,two,three;
...
}
And I am calling the function from main as follows
void main(void)
{
initPhant("data.sparkfun.com", "Public_Key", "Private_Key");
xB_begin(XBEE_BAUD);//uart initialization
// Set up WiFi network
printf("Testing network\n");
// connectWiFi will attempt to connect to the given SSID,
//using encryption mode "encrypt", and the passphrase string given.
printf("log0\n");
connectWiFi("abcd", 2, "qwerty");
// Once connected, print out our IP address
printf("Connected!\n");
....
}
As you see, I am using the printf() calls to log the progress of the execution. But the debugger console prints only these:
Testing network
log0
The next printf() statement is not being printed. Thus I believe that the execution never reaches the function.
Another weird thing here is that the code actually stops running after printing "log0"- when I look at the program counter in the dissambler(a part of the debugger) at this point, the instruction it is stuck at, is labelled "???".
Thanks in advance for your help, I've been cracking my head for several hours on this problem.
The problem is the following:
void connectWiFi(String id, int auth, String psk)
{
printf("log 0.1\n");
char cwTemp2[10];
...
}
You didn't specify what ... contains but you had previously defined
typedef char String[5000];
So, because the line before the connectWiFi call is executed but the first line of the connectWiFi function is not executed, it looks like ... contains String declarations which cause the stack to overflow.
This is especially likely on microcontroller systems that have a limited stack space.
The solution is to not allocate such large strings from the stack. Allocating such large strings from the heap should be avoided too as microcontrollers have limited memory. Better to allocate exactly how many bytes you need.

Why's _itoa causing my program to crash?

The following code just keeps on crashing when it reaches the part with _itoa, I've tried to implement that function instead and then it got even weirder, it just kept on crashing when I ran it without the debugger but worked fine while working with the debugger.
# include "HNum.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <assert.h>
# define START_value 30
typedef enum {
HNUM_OUT_OF_MEMORY = -1,
HNUM_SUCCESS = 0,
} HNumRetVal;
typedef struct _HNum{
size_t Size_Memory;
char* String;
}HNum;
HNum *HNum_alloc(){
HNum* first = (HNum*)malloc(sizeof(HNum));
if(first==NULL){
return NULL;
}
first->String =(char*)malloc(sizeof(START_value));
if(first->String==NULL){
return NULL;
}
first->Size_Memory = START_value; // slash zero && and starting from zero index;
return first;
}
HNumRetVal HNum_setFromInt(HNum *hnum, int nn){
itoa(nn,hnum->String,10);
}
void main(){
HNum * nadav ;
int h = 13428637;
nadav = HNum_alloc();
nadav->String="1237823423423434";
HNum_setFromInt(nadav,h);
printf("nadav string : %s \n ",nadav->String);
//printf("w string %s\n",w->String);
//printf("nadav string %s\n",nadav->String);
HNum_free(nadav);
}
I've been trying to figure this out for hours and couldn't come up with anything...
The IDE I'm using is Visual Studio 2012 express, the crash shows the following:
"PROJECT C.exe has stopped working
windows can check online for a solution to the program."
first->String =(char*)malloc(sizeof(START_value));
should be
first->String = malloc(START_value);
The current version allocates space for sizeof(int)-1 characters (-1 to leave space for the nul terminator). This is too small to hold your target value so _itoa writes beyond memory allocated for first->String. This results in undefined behaviour; it is quite possible for different runs to fail in different places or debug/release builds to behave differently.
You also need to remove the line
nadav->String="1237823423423434";
which leaks the memory allocated for String in HNum_alloc, replacing it with a pointer to a string literal. This new pointer should be considered to be read-only; you cannot write it it inside _itoa
Since I'm not allowed to comment:
simonc's answer is correct. If you find the following answer useful, you should mark his answer as the right one:P
I tried that code myself and the only thing missing is lets say:
strcpy(nadav->String, "1237823423423434"); INSTEAD OF nadav->String="1237823423423434";
and
first->String = malloc(START_value); INSTEAD OF first->String =(char*)malloc(sizeof(START_value));
Also, maybe you'd have to use _itoa instead of itoa, that's one of the things I had to change in my case anyhow.
If that doesn't work, you should probably consider using a different version of VS.

Resources