Does it analysis the lifecycle of the variable and simply insert the cleanup function call at the right place? Does it have any overhead cost?
I've written two pieces of simple code to compare the performance, and compiled them without optimization.
code1:
#include <stdio.h>
#include <stdlib.h>
void clean_up(int **final_value)
{
free(*final_value);
}
int main(int argc, char **argv)
{
for (int i = 0; i < 10000000; i++) {
int *avar = malloc(sizeof(int));
clean_up(&avar);
}
return 0;
}
code2:
#include <stdio.h>
#include <stdlib.h>
void clean_up(int **final_value)
{
free(*final_value);
}
int main(int argc, char **argv)
{
for (int i = 0; i < 10000000; i++) {
int *avar __attribute__ ((__cleanup__(clean_up))) = malloc(sizeof(int));
}
return 0;
}
And their performance are quite similar.
You'll better compile with some optimization, in particular if you want to look into the generated assembler code (compile with gcc -S -fverbose-asm -O)
The intuition behind __attribute__((cleanup)) is that GCC is in fact a compiler for all of C, C++, Ada, Fortran, Go.... That attribute is forcing the same internal representation than for C++ destructors of local variables. The cleanup happens at end of current block scope (e.g. at closing brace } of the block). So the compiler is transforming your code2 with cleanup into the equivalent of code1.
The thing for destructors of global or static variables (which are run after main has returned) is __attribute__((destructor)) on functions (which are also run at dlclose time for plugins).
So to understand these attributes, you'll better think in C++ terms.
My opinion is that if you need these cleanup attributes, you should code your thing in C++ not in C. Your code would be much more readable and less compiler dependent. I feel that cleanup is in practice only useful in generated C code. I never used it (and feel that when I need it, I should switch to C++).
The cleanup function is called when the variable goes out of scope. It doesn't care, whether this would leave other pointers dangling.
Related
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.
For a very specific project, I need to write a 16-bit program in C and I'm using Microsoft QuickC in MS-DOS to write this program. Now I'm pretty sure the syntax of my program is correct but the program just won't compile and it thinks I have syntax errors. Is this because C-compilers in MS-DOS using an older version of C with different syntax?
#include<stdio.h>
main()
{
printf("Hello World!");
}
Not even that simple hello world program will compile and run.
you should define main as int
so change your code to :
int main() { // define main as an int returning function
// your code
return 0; // Also make sure you have return statement in main
}
and it will compile
Here is what it says in the standards:
1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int :
int main(void) { /* ... */ }
Edit:
Ok from your comments .. you are now getting this error:
C1024: cannot open include file 'stdio.h'
Here is a cause and solution from microsoft:
http://support.microsoft.com/kb/97809
You can't omit the type of the function main, or any other C function, for that matter. So, you want
void main() { ... }
or
int main(int argc, char **argv) { ... }
although with the latter one the compiler will usually require you to return a value.
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))
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.
I am reading Microsoft's CRT source code, and I can come up with the following code, where the function __initstdio1 will be executed before main() routine.
The question is, how to execute some code before entering the main() routine in VC (not VC++ code)?
#include <stdio.h>
#pragma section(".CRT$XIC",long,read)
int __cdecl __initstdio1(void);
#define _CRTALLOC(x) __declspec(allocate(x))
_CRTALLOC(".CRT$XIC") static pinit = __initstdio1;
int z = 1;
int __cdecl __initstdio1(void) {
z = 10;
return 0;
}
int main(void) {
printf("Some code before main!\n");
printf("z = %d\n", z);
printf("End!\n");
return 0;
}
The output will be:
Some code before main!
z = 10
End!
However, I am not able to understand the code.
I have done some google on .CRT$XIC but no luck is found. Can some expert explain above code segment to me, especially the followings:
What does this line _CRTALLOC(".CRT$XIC") static pinit = __initstdio1; mean? What is the significance of the variable pinit?
During compilation the compiler (cl.exe) throws a warning saying as below:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
stdmacro.c
stdmacro.c(9) : warning C4047: 'initializing' : 'int' differs in levels of indirection from 'int (__
cdecl *)(void)'
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:stdmacro.exe
stdmacro.obj
What is the corrective action needs to be done to remove the warning message?
Thanks in advance.
Added:
I have modified the code and give type to pinit as _PIFV. Now the warning message is gone.
The new code is as follows:
#include <stdio.h>
#pragma section(".CRT$XIC1",long,read)
int __cdecl __initstdio1(void);
typedef int (__cdecl *_PIFV)(void);
#define _CRTALLOC(x) __declspec(allocate(x))
_CRTALLOC(".CRT$XIC1") static _PIFV pinit1 = __initstdio1;
int z = 1;
int __cdecl __initstdio1(void) {
z = 100;
return 0;
}
int main(void) {
printf("Some code before main!\n");
printf("z = %d\n", z);
printf("End!\n");
return 0;
}
A simple way to do this.
#include <iostream>
int before_main()
{
std::cout << "before main" << std::endl;
return 0;
}
static int n = before_main();
void main(int argc, char* argv[])
{
std::cout << "in main" << std::endl;
}
This is what _CRTALLOC is defined as:
extern _CRTALLOC(".CRT$XIA") _PVFV __xi_a[];
extern _CRTALLOC(".CRT$XIZ") _PVFV __xi_z[];// C initializers
extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];// C++ initializers
It's a table of things to pre-initialise, of which a pointer to your function __initstdio1 is placed.
This page described CRT initialisation:
http://msdn.microsoft.com/en-us/library/bb918180.aspx
In C++ at least, you don't need all that implementation specific stuff:
#include <iostream>
struct A {
A() { std::cout << "before main" << std::endl; }
};
A a;
int main() {
std::cout << "in main" << std::endl;
}
I wrote an award-winning article about this on CodeGuru a while ago.
There's some information here (search for CRT). The significance of variable pinit is none, it's just a piece of data placed in the executable, where the runtime can find it. However, I would advise you to give it a type, like this:
_CRTALLOC(".CRT$XIC") static void (*pinit)()=...
The linker warning probably just warns you you have a function that has int return type, but doesn't return anything (probably you'd better change the return type to void).
Even in C, there is a need for some code to be run before main() is entered, if only to transform the command line into the C calling convention. In practice, the standard library needs some initialization, and the exact needs can vary from compile to compile.
The true program entry point is set at link time, and is usually in a module named something like crt0 for historical reasons. As you've found, the source to that module is available in the crt sources.
To support initializations that are discovered at link time, a special segment is used. Its structure is a list of function pointers of fixed signature, which will be iterated early in crt0 and each function called. This same array (or one very much like it) of function pointers is used in a C++ link to hold pointers to constructors of global objects.
The array is filled in by the linker by allowing every module linked to include data in it, which are all concatenated together to form the segment in the finished executable.
The only significance to the variable pinit is that it is declared (by the _CRTALLOC() macro) to be located in that segment, and is initialized to the address of a function to be called during the C startup.
Obviously, the details of this are extremely platform-specific. For general programming, you are probably better served by wrapping your initialization and your current main inside a new main():
int main(int argc, char **argv) {
early_init();
init_that_modifies_argv(&argc, &argv);
// other pre-main initializations...
return real_main(argc,argv);
}
For special purposes, modifying the crt0 module itself or doing compiler-specific tricks to get additional early initialization functions called can be the best answer. For example, when building embedded systems that run from ROM without an operating system loader, it is common to need to customize the behavior of the crt0 module in order to have a stack at all on which to push the parameters to main(). In that case, there may be no better solution than to modify crt0 to initialize the memory hardware to suit your needs.