I saw redefine function here using macro in c. So I am interesting is it possible to redefine main function?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
printf("Original main function\n");
return 0;
}
int _main(int argc, char **argv)
{
printf("New Original main function\n");
return main(argc, argv);
}
#ifdef DEBUG
#define main(argc, argv) _main(argc, argv)
#endif
Code compiled with out any problem but I am getting:
Original main function
So I am wondering why it does not work? When I use same techniques for malloc and free functions it works perfect. So what is wrong?
Why I want to do something like this? I want to do some code before main function will be executed. Is it possible in this way? if not is there are some other way?
P.S.: Sorry I did not mention in question. I am using gcc in Ubuntu OS. If you are down voting please give a reason in comments. You comments is very useful to my further development.
If you want to change entry point of your program, you don't need play with defines. You can use linker's -e option for that:
gcc -Wl,-e,__main ...
Please note extra underscore. Depending on some options, the symbol name can be different.
If your question is really: "can i execute code before main?" Then the answer is an emphatic YES.
Since you are using GCC, you can use function attributes (http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) to mark a function as a constructor.
void pre_main_function (void) __attribute__ ((constructor));
A useful example can be found at http://www.geeksforgeeks.org/functions-that-are-executed-before-and-after-main-in-c/
EDIT
The following syntax can also be used:
__attribute__ (( constructor(n) ))
where n specifies the priority, allowing you to mark multiple functions to be executed before main whilst giving you control over the execution order ( the lower the value of n, the earlier the function is executed.
Your #define does not change the main function at all - it is a macro preprocessor.
The only effect of your #define will be to change the call to main in _main into a recursive call to _main(). But since _main is not called, this is dead code. This is what your code looks like after the preprocessor has run...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
printf("Original main function\n");
return 0;
}
int _main(int argc, char **argv)
{
printf("New Original main function\n");
return _main(argc, argv); /* recursive call due to macro replace */
}
This then leads to the next question - which is why redefine main at all? If you want some entirely different code to run on debug simply declare main as
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
#ifdef DEBUG
return debugApp( argc, argv);
#else
return productionApp( argc, argv);
#endif
}
N.B Just because you can do something doesn't mean you should do it. :-)
Related
Say I have a library I am making and I want to call a function rename or puts, how can I keep the original rename and puts from stdlib or stdio or whatever, and yet have my own function be puts?
#include <stdio.h>
alias puts original_puts;
void
puts(char *c) {
original_puts(c);
}
How can I accomplish something to this effect?
You can't alias library functions, but you can alias your own using preprocessor directives.
For example:
mylib.h:
#include <stdio.h>
void my_puts(char *c);
#define puts(arg) my_puts(arg)
mylib.c:
void my_puts(char *c)
{
(puts)(c);
}
Now, anytime someone calls puts, it substitutes a call to my_puts instead. Also, when you want to call the "real" function in your wrapper, you can put the function name in quotes. Because the macro that does the substitution is a function-like macro, the parenthesis prevent the substitution from happening.
If compiling with gcc or clang, you can wrap the symbol with -Wl,--wrap:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int __real_puts(const char *c);
int __wrap_puts(const char *c) {
__real_puts("Hello");
__real_puts(c);
return 0;
}
int main(int argc, char const *argv[]) {
puts("world");
}
$ gcc src.c -Wl,--wrap=puts && ./a.out
Hello
world
I want to add a system call docs and I have one asmlinkage function. The function must take 2 parameters. These parameters are coming from the c docs which I calls system call. At below I showed the c docs :
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(int argc,char*argv[])
{
long int amma = syscall(335,argc,argv);
printf("System call functions returned %ld\n", amma);
return 0;
}
As you see I want to pass argc and argv char array for making some file operations.
Firstly I wrote my asmlinkage function like that :
asmlinkage long function(int argc,char *argv[]){
if(argc==2)
printk(KERN_INFO "Hello world"); // but it can not take argc
}
In addition I added to line to syscalls.h:
asmlinkage function(int,char*[]);
Then I compiled correctly but when I started to run my code in userspace my syscall killed.
I found a link in this website but I couldn't compile it. Topic owner used "SYSCALL_DEFINE" but I faced many code mistake which I could not understand.
I was playing around with symbols and function pointers recently and noticed that though the following code runs fine:
#include <stdio.h>
int main(int argc, const char * argv[]) {
printf("%p\n",printf); // <--this line makes it work
int (*printfptr)(const char * restrict, ...);
printfptr = 0x1001fe910;
(*printfptr)("Hello world\n");
return 0;
}
This does not:
#include <stdio.h>
int main(int argc, const char * argv[]) {
// printf("%p\n",printf); // <-- commenting this out breaks it
int (*printfptr)(const char * restrict, ...);
printfptr = 0x1001fe910;
(*printfptr)("Hello world\n");
return 0;
}
(EXC_BAD_ACCESS)
How come dereferencing the exact same pointer causes issues when there is no reference to printf in the code? Even this works fine:
#include <stdio.h>
int main(int argc, const char * argv[]) {
int (*printfptr)(const char * restrict, ...);
printfptr = 0x1001fe910;
(*printfptr)("Hello world\n");
return 0;
}
void *_ = printf; // <-- because of this
Why is this?
On shared objects (.so) the symbols are really resolved only at the moment of first use. By default the linker sets the option -z lazy which tells:
When generating an executable or shared library, mark it to
tell the dynamic linker to defer function call resolution to
the point when the function is called (lazy binding), rather
than at load time. Lazy binding is the default.
You can change that behaviour by providing option -z now.
man ld for all gory details.
EDIT: Resolving a symbol is done with dynamic link API on POSIX systems. Functions dlsym(), dlopen(), dlclose() and dlerror() defined in <dlfcn.h>. This edition added so that you can search for these names.
I have a lot of unused macros in my code.
So, I am wondering.. If a macro is unused, does it takes up memory space in your program?
The type of macros I have are just the basic ones.
Example:
#define TEST_ID 0
Macros will be expanded during preprocessing phase so they don't exist in your program. They just take some space in your source code.
Edit:
In response to Barmar's comment, I did some research.
MSVC 2012: In debug build (when all optimizations are disabled, /Od), adding lines of macros won't cause the growth of the size of your program.
GCC: does provide a way to include macro in debugging information as long as you compile your program with a specific flag. See here. (I didn't know that before myself. Thank you, #Barmar, #Sydius)
No, doesn't takes space until is used, for this two pieces of code:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%d %s\n", argc, argv[0]);
return 0;
}
and
#include <stdio.h>
#define TEST_ID 0
int main(int argc, char *argv[])
{
printf("%d %s\n", argc, argv[0]);
return 0;
}
The ASM generated with gcc -S is the same.
macro is replaced by preprocessor before compilng start.
if you define a macro, and doesn't use it, the compiler will never see it.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
char a[]="Hello";
void * thread_body(void * param) {
while(1)
printf("%s\n", param);
}
int main(int argc, char *argv[]) {
pthread_t threadHello;
int code;
pthread_create(&threadHello, NULL, thread_body, a);
pthread_cancel(threadHello);
pthread_exit(0);
}
When I compile and run this under Solaris 10 (SunOS 5.10), it doesn't stop. But under Linux it works as intended.
Per POSIX, printf (and all of stdio) may be a cancellation point. It is not required to be. I suspect Solaris just doesn't choose to make it one. Have you tried another function like sleep here?
If you really need printf to be cancellable, you'll probably need to implement your own printf-like function as a wrapper for dprintf, but that won't work so well if you're depending on the builtin locking functionality of stdio..