Trying to suppress clang false positive leak warning - c

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.

Related

Cannot return correct memory address from a shared lib in C

I have been trying to implement a small simulation to understand memory allocation of malloc(). I created a shared library called mem.c. I am linking the library to the main but cannot pass the correct address of the simulated "heap". Heap is created by a malloc() call in the shared library.
Address in the shared library: 0x55ddaff662a0
Address in the main: 0xffffffffaff662a0
Only last 4 bytes seem to be correct. Rest is set to 0xf.
However, when I #include "mem.c" in the main it works correctly. How can I achieve the same result without including the mem.c. I am trying to solve this without including mem.c or mem.h. I create shared library as this:
gcc -c -fpic mem.c
gcc -shared -o libmem.so mem.o
gcc main.c -lmem -L. -o main
From your comments
I am trying to implement without using #include mem.h or mem.c.
Then you must provide by other means a prototype for the function you're calling. Without an explicit function prototype, following the tradition of K&R and then later ANSI C, undeclared functions are assumed to return an int and take parameters of type int.
EDIT: Essentially you need to write what'd you normally find in a header, somewhere before you make first use of the function. Or of it's a function pointer you need an appropriate variable to store the function pointer.
For example to declare a function that returns an untyped pointer, and an arbitrary, unspecified number of arguments you'd write
void *getAddr();
Note that using the extern keyword here is not required, since extern linkage is always implied for non-static function declarations.
In case you want to dynamically link at runtime (using dlopen / LoadLibrary → dlsym / GetProcAddress), you'd define a function pointer variable
void* (*getAddr_fptr)();
You can set it using dlsym with
*(void**)(&getAddr_fptr) = dlsym(…)
This awkward way of writing it comes due to function pointers being allowed to have a different size and alignment as data pointers (see the dlsym manpage for details).
These days on the majority of platforms int is a 4 byte type and the most common calling convention pass the first few function arguments by register. On x86 (and x86_64) the registers are AX, BX, CX and DX and may be accessed in different sizes, but may read and write with different size (to allow size conversion). This explains why only the first 4 bytes are passed: It's passed via register and only the write to the register is done as a 4 byte wide write. When the function then reads from the register, it does so with a wider type, with the higher value bits set to all 1.
From the comments:
Do you have a declaration for getAddr in your main code?
No I don't have but I am trying to implement without a declaration, is it possible?
Then that's your problem. Without a declaration, the compiler falls back to a default declaration of int getAddr(). This is incompatible with the actual definition which returns a void *, and calling a function through an incompatible declaration triggers undefined behavior.
What probably happened is that when the return value of the function was actually returned you only got back the 4 low-order bytes. Assuming your system is little-endian, and int is 4 bytes, and a void * is 8 bytes, this would explain the low bits being the same.
You must include a valid declaration before the function is called. It doesn't necessarily have to reside in a header file, but it has to be visible at the point the call happens.
I'm assuming you're trying to accomplish something like this? For mem.c
#include <stdlib.h>
#include <stdio.h>
void* getAddr() {
char *heap = (char *)malloc(10);
printf("%p\n", (void*)heap);
return heap;
}
And then without including any headers for the mem.c functions, you'd probably create a library out of mem.c as you've already mentioned in the question and have something as follows in main.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
typedef void* (*getAddr)(); //prototype for getAddr() in mem.c
int main() {
void* handle = dlopen("./libmem.so", RTLD_LAZY);
if(handle) {
void* fn = dlsym(handle, "getAddr");
if(fn) {
void* addr = ((getAddr)(fn))();
printf("%p\n", addr);
free(addr);
addr = NULL;
} else {
printf("Failed to dlsym %s\n", dlerror());
}
} else {
printf("Failed to dlopen %s\n", dlerror());
}
}
EDIT: For OP's purpose as #Zilog80 mentioned, since the library is being linked with main executable, the dlopen() part can be gotten rid of and main.c can be simplified as
#include <stdio.h>
#include <stdlib.h>
extern void* getAddr(); //prototype for getAddr() in mem.c
int main() {
void* addr = getAddr();
printf("%p\n", addr);
free(addr);
addr = NULL;
}
And used similar compilation commands as OP i.e.
gcc -shared -o libmem.so -fpic mem.c
gcc main.c -lmem -L . -o main
while executing
LD_LIBRARY_PATH=. ./main

How do I make LeakSanitizer ignore end of program leaks

I want to use LeakSanitizer to detect leaked memory, but the style of the program I am using does not free memory before exit. This is fairly common in my experience.
I want to detect this leak:
int main(int argc, char const *argv[])
{
char *p = malloc(5);
p = 0;
return 0;
}
And ignore this leak:
int main(int argc, char const *argv[])
{
char *p = malloc(5);
return 0;
}
You want LSan to report only unreachable leaks i.e. pointers which are guaranteed to be leaked by the program. Problem is that by default LeakSanitizer runs it's checks at the end of the program, often after global C++ dtors have completed and their contents is no longer considered accessible. So when LSan finally runs, it has to assume that lots of stuff is no longer reachable. To work around this issue you can add
#include <lsan_interface.h>
...
#ifdef __SANITIZE_ADDRESS__
__lsan_do_leak_check();
__lsan_disable();
#endif
before returning from main (inspired by Issue 719 and llvm discussion).
PS: Be careful with extremely simple examples like the ones you post above. GCC will often remove unused assignments and allocations even at -O0 so always check that assembler matches your expectations.

FreeLibrary leak on VC14 but not on VC9

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.

glibc - force function call (no inline expansion)

I have a question regarding glibc function calls. Is there a flag to tell gcc not to inline a certain glibc function, e.g. memcpy?
I've tried -fno-builtin-memcpy and other flags, but they didn't work. The goal is that the actual glibc memcpy function is called and no inlined code (since the glibc version at compile time differs from the one at runtime). It's for testing purposes only. Normally I wan't do that.
Any solutions?
UPDATE:
Just to make it clearer: In the past memcpy works even with overlapping areas. This has changed meanwhile and I can see this changes when compiling with different glibc versions. So now I want to test if my old code (using memcpy where memmove should have been used) works correct or not on a system with a newer glibc (e.g. 2.14). But to do that, I have to make sure, that the new memcpy is called and no inlined code.
Best regards
This may not be exactly what you're looking for, but it seems to force gcc to generate an indirect call to memcpy():
#include <stdio.h>
#include <string.h>
#include <time.h>
// void *memcpy(void *dest, const void *src, size_t n)
unsigned int x = 0xdeadbeef;
unsigned int y;
int main(void) {
void *(*memcpy_ptr)(void *, const void *, size_t) = memcpy;
if (time(NULL) == 1) {
memcpy_ptr = NULL;
}
memcpy_ptr(&y, &x, sizeof y);
printf("y = 0x%x\n", y);
return 0;
}
The generated assembly (gcc, Ubuntu, x86) includes a call *%edx instruction.
Without the if (time(NULL) == 1) test (which should never succeed, but the compiler doesn't know that), gcc -O3 is clever enough to recognize that the indirect call always calls memcpy(), which can then be replaced by a movl instruction.
Note that the compiler could recognize that if memcpy_ptr == NULL then the behavior is undefined, and again replace the indirect call with a direct call, and then with a movl instruction. gcc 4.5.2 with -O3 doesn't appear to be that clever. If a later version of gcc is, you could replace the memcpy_ptr = NULL with an assignment of some actual function that behaves differently than memcpy().
In theory:
gcc -fno-inline -fno-builtin-inline ...
But then you said -fno-builtin-memcpy didn't stop the compiler from inlining it, so there's no obvious reason why this should work any better.
#undef memcpy
#define mempcy your_memcpy_replacement
Somewhere at the top but after #include obviously
And mark your_memcpy_replacement as attribute((noinline))

How to run constructor even if "-nostdlib" option is defined

I have a dynamic library that contains a constructor.
__attribute__ ((constructor))
void construct() {
// This is initialization code
}
The library is compiled with -nostdlib option and I cannot change that. As a result there are no .ctor and .dtor sections in library and the constructor is not running on the library load.
As written there there should be special measures that allow running the constructor even in this case. Could you please advice me what and how that can be done?
Why do you need constructors? Most programmers I work with, myself included, refuse to use libraries with global constructors because all too often they introduce bugs by messing up the program's initial state when main is entered. One concrete example I can think of is OpenAL, which broke programs when it was merely linked, even if it was never called. I was not the one on the project who dealt with this bug, but if I'm not mistaken it had something to do with mucking with ALSA and breaking the main program's use of ALSA later.
If your library has nontrivial global state, instead see if you can simply use global structs and initializers. You might need to add flags with some pointers to indicate whether they point to allocated memory or static memory, though. Another method is to defer initialization to the first call, but this can have thread-safety issues unless you use pthread_once or similar.
Hmm missed the part that there where no .ctor and .dtor sections... forget about this.
#include <stdio.h>
#include <stdint.h>
typedef void (*func)(void);
__attribute__((constructor))
void func1(void) {
printf("func1\n");
}
__attribute__((constructor))
void func2(void) {
printf("func2\n");
}
extern func* __init_array_start;
int main(int argc, char **argv)
{
func *funcarr = (func*)&__init_array_start;
func f;
int idx;
printf("start %p\n", *funcarr);
// iterate over the array
for (idx = 0; ; ++idx) {
f = funcarr[idx];
// skip the end of array marker (0xFFFFFFFF) on 64 bit it's twice as long ;)
if (f == (void*)~0)
continue;
// till f is NULL which indicates the start of the array
if (f == NULL)
break;
printf("constructor %p\n", *f);
f();
}
return 0;
}
Which gives:
Compilation started at Fri Mar 9 09:28:29
make test && ./test
cc test.c -o test
func2
func1
start 0xffffffff
constructor 0x80483f4
func1
constructor 0x8048408
func2
Probably you need to swap the continue and break if you are running on an Big Endian system but i'm not entirely sure.
But just like R.. stated using static constructors in libraries is not so nice to the developers using your library :p
On some platforms, .init_array/.fini_array sections are generated to include all global constructors/destructors. You may use that.

Resources