I am using a third party library which apparently has a memory leak that we first discovered when upgrading from Visual Studio 2008 (VC9.0) to Visual Studio 2015 (VC14.0). On Windows I load the library at run-time using LoadLibrary and when done using it I unload it using FreeLibrary. When compiling and linking with VC9.0 all memory allocated by the library gets freed on FreeLibrary while using VC14.0 some memory is never freed. The memory profile for my test program below can be seen here: http://imgur.com/a/Hmn1S.
Why is the behavior different for VC9.0 and VC14.0? And can one do anything to avoid the leak without changing the source of the library, like mimic the behavior of VC9.0?
The only thing I could find here on SO is this: Memory leaks on DLL unload which hasn't really helped me, though one answer hints at some hacky solution.
I have made a minimal working example to show that it is not specific to the library. First I create a small library in C with a function that allocates some memory and never deallocates it:
leaklib.h:
#ifndef LEAKLIB_H_
#define LEAKLIB_H_
__declspec( dllexport ) void leak_memory(int memory_size);
#endif
leaklib.c:
#include "leaklib.h"
#include <stdio.h>
#include <stdlib.h>
void leak_memory(int memory_size)
{
double * buffer;
buffer = (double *) malloc(memory_size);
if (buffer != NULL)
{
printf("Allocated %d bytes of memory\n", memory_size);
}
}
And then a program that loads the library, calls the memory leak function, and then unloads the library again - repeatedly so that we can track the memory over time.
memleak.c:
#include <windows.h>
#include <stdio.h>
int main(void)
{
int i;
HINSTANCE handle;
int load_success;
void (*leak_memory)(int);
int dll_unloaded;
Sleep(30000);
for (i = 0; i < 100; ++i)
{
handle = LoadLibrary(TEXT("leaklib.dll"));
leak_memory = GetProcAddress(handle, "leak_memory");
printf("%d: leaking memory...\n", i);
leak_memory(50*1024*1024);
printf("ok\n\n");
Sleep(3000);
dll_unloaded = FreeLibrary(handle);
if (!dll_unloaded)
{
printf("Could not free dll'");
return 1;
}
Sleep(3000);
}
return 0;
}
I then build the library with:
cl.exe /MTd /LD leaklib.c
and the program with
cl.exe memleak.c
with cl.exe from either VS9.0 or VS14.0.
The real problem is that VC9 inadvertently deallocated memory that a reasonable program might expect to still be there - after all, free() wasn't called. Of course, this is one of those areas where the CRT can't please everybody - you wanted the automagic free behavior.
Underlying this is the fact that FreeLibrary is a pretty simple Win32 function. It removes a chunk of code from your address space. You might get a few final calls to DllMain, but as DllMain's documentation notes: you can't do much there. One thing that's especially hard is figuring out what memory would need to be freed, other than DLL's code and data segment.
Related
I have a C program which uses malloc (it could also have been C++ with new). I would like to test my program and simulate an "out of memory" scenario.
I would strongly prefer running my program from within a bash or sh shell environment without modifying the core code.
How do I make dynamic memory allocations fail for a program run?
Seems like it could be possible using ulimit but I can't seem to find the right parameters:
$ ulimit -d 50
$ ./program_which_heap_allocates
./program_which_heap_allocates: error while loading shared libraries: libc.so.6: cannot map zero-fill pages
$ ulimit -d 51
bash: ulimit: data seg size: cannot modify limit: Operation not permitted
I'm having trouble running the program in such a way that dynamic linking can occur (such as stdlib) but not the allocations from my program.
If you are under Linux and using glibc then there are Hooks for Malloc. The hooks allow you to catch calls to malloc and make them randomly fail.
Your test suite could use an environment variable to tell the code to insert the malloc hook and which call of malloc to fail. E.g. if you set FOOBAR_FAIL_MALLOC=10 then your malloc hook would count down and let the 10th use of malloc return 0.
FOOBAR_FAIL_MALLOC=0 could simply report the numbers of mallocs in a testcase. You would then run the test once with FOOBAR_FAIL_MALLOC=0 and capture the number of mallocs involved. Then repeat for FOOBAR_FAIL_MALLOC=1 to N to test every single malloc.
Unless after a failure of malloc you have more mallocs. Then you have to think of something more complex to specify which mallocs should fail.
You could also just make the hook fail randomly. Given enough runs every malloc call would fail at some point.
Note: a C++ new should also hot the malloc hook
You can have your test program include the .c under test and use a #define to override calls to malloc.
For example:
prog.c:
#include <stdio.h>
#include <stdlib.h>
void *foo(int x)
{
return malloc(x);
}
test.c:
#include <stdio.h>
#include <stdlib.h>
static char buf[100];
static int malloc_fail;
void *test_malloc(size_t n)
{
if (malloc_fail) {
return NULL;
} else {
return buf;
}
}
#define malloc(x) test_malloc(x)
#include "prog.c"
#undef malloc
int main()
{
void *p;
malloc_fail=0;
p = foo(5);
printf("buf=%p, p=%p\n", (void *)buf, p); // prints same value both times
malloc_fail=1;
p = foo(4);
if (p) {
printf("buf=%p, p=%p\n", (void *)buf, p);
} else {
printf("p is NULL\n"); // this prints
}
return 0;
}
This question already has answers here:
Find size of a function in C
(9 answers)
Closed 4 years ago.
I am writing code for an embedded system where it is more efficient to copy code from ROM to the SOC's internal memory then execute it. Is there any way to programmatically get the size in bytes of the function so I can use a function like memcpy to copy the function's instructions to internal memory.
Is there a better way to do this?
Is there a better way to do this?
There likely is, and I truly hope someone else responds with an answer that provides a simpler approach, but for now I'll shed some details on your suggested method.
If the program is compiled in ELF format (I don't know for the other formats), all your functions will be included in the .text section of the ELF file. You can use the symbol table to find this function in the text section. To get the size of this function, you might be able to use the st_size member of the Elf64_Sym or Elf32_Sym struct, but I'm not entirely certain that will give the correct size. What you could do (a little hacky, admittedly) is iterate through the other symbols, and find the one immediately after it, and subtract to get the size. Of course you'd have to keep in mind alignment rules, but that's not too much of an issue- if you copy extra bytes, they won't be executed anyways.
Also keep in mind that some code get compiled with certain assumptions about its offset in memory. You'll might need to manually patch the GOT and/or PLT if you copy the function directly into memory. Know you should probably compile the function you want to include with -PIC and -fPIC for position independent code, at least in GCC.
If you need more details on how to access the symbol table, or the text section of your ELF, I could add more details.
With some compilers you can get a function size by computing the difference between the function's address and the address of another function that immediatly follows the first one.
But it really depends of the compiler. With Visual C++ for example, both functions has to be static functions. With GCC, it does not work anymore if optimization O2 or better is activated.
And even if you manage to copy your function elsewhere in memory, you may not be able to use it, especially if it refers other functions, or if it refers global/static variables, or if the code is not position independant, etc.
So this is a simple solution, it may work in your case, but it can't be considered as a general solution.
Below there's an example that works with gcc and visual C++, tested on windows 10 and WSL (do not activate optimizations with gcc).
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#endif
#ifdef __linux
#include <sys/mman.h>
#endif
// The function to copy
static int fib(int m)
{
int v1 = 0, v2 = 1, n;
if (m == 0) return 0;
for (n = 1; n < m; n++)
{
int v = v1 + v2;
v1 = v2;
v2 = v;
}
return v2;
}
static void endFib(void)
{
// This function follow immediatly the fib function
// and it exists only to get its address and compute the size of fib function
}
int main(int argc, char *argv)
{
long sizeFib;
int (*copyFib)(int);
printf("&fib=%p\n", (char *)fib);
sizeFib = (char *)endFib - (char *)fib;
printf("size of fib : %ld\n", sizeFib);
printf("fib(8) : %d\n", fib(8));
// For the example the allocated copy must be in an executable part of the memory.
#ifdef _WIN32
copyFib = VirtualAlloc(NULL, sizeFib, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#endif
#ifdef __linux
copyFib = mmap(NULL, sizeFib, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
#endif
memcpy(copyFib, fib, sizeFib);
printf("©Fib=%p\n", copyFib);
printf("copyFib(8) : %d\n", copyFib(8));
return 0;
}
I am using clang static analysis under Xcode 6.4 (6E35b), and getting a false positive warning about a potential memory leak. I do explicitly free the memory in question, but the freeing happens in a different compilation unit. Here is my MWE:
file2.c: Performs the actual freeing.
#include <stdlib.h>
void my_free(const void* p) {
free((void*) p);
}
file1.c: Allocates memory and explicitly frees it through an external function.
#include <stdlib.h>
void my_free(const void* p);
int main(int argc, char* argv[]) {
void* data = malloc(1);
if(data) my_free(data);
return 0; /* <-- "Potential leak of memory pointed to by 'data'" */
}
When I define my_free() in the same compilation unit as its invocation, no warning is generated, but of course I need to invoke my_free() from a large number of different source files.
I have read through FAQ and How to Deal with Common False Positives, but it does not address my situation. What can I do to assure clang that I really am freeing the memory in question?
In case the version information is relevant:
% clang --version
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
One way to fix that would be to add code specific for the analyser, in your header file:
#ifdef __clang_analyzer__
#define my_free free
#endif
This will make the static analyser think you're using the classic free function and stop complaining.
I wrote a simple c program to simulate a memory leak. But it crashes when i try to run it.
#include <stdio.h>
#include <stdlib.h>
void memory_leak(void);
int main()
{
memory_leak();
return EXIT_SUCCESS;
}
void memory_leak()
{
int i = 100;
memory_leak();
}
I use MinGW gcc compiler.
You are producing a stack overflow - by calling your function memory leak recursively.
Your version of memory_leak allocates a local ("stack") variable that will be released/destroyed/deallocated when the function exits.
To actually create a memory leak, you need to allocate memory from the heap (e.g. using new or malloc).
void* memory_leak()
{
return malloc(10);
}
[Don't unconditionally call memory_leak within memory_leak.]
Is there a way to hook the malloc/free function call from a C application it self?
malloc() and free() are defined in the standard library; when linking code, the linker will search the library only for symbols that are not already resolved by eailier encountered object code, and object files generated from compilation are always linked before any libraries.
So you can override any library function simply by defining it in your own code, ensuring that it has the correct signature (same name, same number and types of parameters and same return type).
Yes you can. Here's an example program. It compiles and builds with gcc 4.8.2 but does not do anything useful since the implementations are not functional.
#include <stdlib.h>
int main()
{
int* ip = malloc(sizeof(int));
double* dp = malloc(sizeof(double));
free(ip);
free(dp);
}
void* malloc(size_t s)
{
return NULL;
}
void free(void* p)
{
}
Not sure if this counts as "overwriting', but you can effectively change the behavior of code that calls malloc and free by using a macro:
#define malloc(x) my_malloc(x)
#define free(x) my_free(x)
void * my_malloc(size_t nbytes)
{
/* Do your magic here! */
}
void my_free(void *p)
{
/* Do your magic here! */
}
int main(void)
{
int *p = malloc(sizeof(int) * 4); /* calls my_malloc */
free(p); /* calls my_free */
}
You may need LD_PRELOAD mechanism to replace malloc and free.
As many mentioned already, this is very platform specific. Most "portable" way is described in an accepted answer to this question. A port to non-posix platforms requires finding an appropriate replacement to dlsym.
Since you mention Linux/gcc, hooks for malloc would probably serve you the best.
Depending on the platform you are using, you may be able to remove the default malloc/free from the library and add your own using the linker or librarian tools. I'd suggest you only do this in a private area and make sure you can't corrupt the original library.
On the Windows platform there is a Detour library. It basically patches any given function on the assembler level. This allows interception of any C library or OS call, like CreateThread, HeapAlloc, etc. I used this library for overriding memory allocation functions in a working application.
This library is Windows specific. On other platforms most likely there are similar libraries.
C does not provide function overloading. So you cannot override.