Hi I am trying to create a counter that will just count the number of times the system call vfork() has been called in fork.c in the Linux kernel source. I'am following how total_forks is implemented. Total_forks is defined in sched.h. But I can't find where it is initialized to zero.
I'm guessing you are talking about the Linux kernel, and the variable declared in sched.h and defined here. It's a global variable (defined at file scope and not static) - these are implicitly initialized to zero. Try this in you own code:
#include <stdio.h>
int var;
int main( int argc, char* argv[] ) {
printf( "var is %d\n", var );
return 0;
}
I'm unfamiliar with the source you're looking at, but a few thoughts spring to mind:
It may be initialized to 1 when init is started.
It may be initialized to 0 because it is in the BSS segment; the runtime system knows to initialize a portion of memory for variables and clears it all before giving it to the 'main' kernel process at early boot.
Related
I was asked these 2 questions during an interview. I guess the address of a static variable will be the same no matter where it is declared. It will also have the same address from run to run. Correct me if I am wrong.
If a static variable is declared out side of a function, will the memory address be the same as if it's declared in a function?
If a static variable is declared out side of a function, will it have the same address every time you run the program?
Cunningham's Law will ensure quick correction of my mistakes:
global and local static variables are treated similarly so they may indeed end up at the same address when moved:
#include <stdio.h>
#ifdef GLOBAL
static int i;
#endif
// static int j;
#ifndef GLOBAL
void f(void) {
static int i;
printf("local: %p\n" , (void *) &i);
}
#endif
int main() {
#ifdef GLOBAL
printf("global: %p\n" , (void *) &i);
#else
f();
#endif
}
You need to disable address randomization to observe it:
$ sudo bash -c 'echo 0 > /proc/sys/kernel/randomize_va_space';\
gcc 1.c && ./a.out &&\
gcc -DGLOBAL 1.c && ./a.out;\
sudo bash -c 'echo 2 > /proc/sys/kernel/randomize_va_space'
local: 0x555555558034
global: 0x555555558034
If you add another global static int j (commented out above) after the global i then the effect goes away:
local: 0x555555558038
global: 0x555555558034
So call me maybe!?
No. Modern operating systems, specifically the program loader, use address space layout randomization
(ASLR) so the address changes on every execution:
$ ./a.out && ./a.out
global: 0x563bcce14034
global: 0x55cd4a497034
static variables may or may not have the same address in memory when declared globally or locally in the body of a function. The fact is nothing can be assumed about these addresses: the C Standard only guarantees that they compare different from the null pointer and different from the addresses of other data objects defined in a C module (albeit compiler extensions can force some symbols to alias one another).
Modern operating systems use address randomisation to make it more difficult for attackers to exploit software flaws, so the addresses may indeed differ from one run to another.
Answering such questions in an interview is tricky: the interviewer's assumptions might be outdated, but a substantiated answer should get you a good mark.
When you have multiple C files, say main.c and process.c I was trying to understand where variables declared outside of functions in both cases are stored.
// this is main.c
#include <stdio.h>
#include "process.h"
int foo = 1;
void main() {
int count = get_counter();
}
// this is process.c
#include <stdio.h>
int counter = 0;
int get_counter() {
return counter;
{
So when you have two c files, your main.c and a process.c, you can call get_counter() in main.c and it will return the value from the process.c file. What I was trying to understand is where the compiler, or how it stores int foo in main.c and int count in process.c? Is this part of some data storage section? It is not on the stack right? It also seems having a separate process.c file makes it so it is not a global variable.
I have been really trying to understand how variables scope is handled and can get a little tricky for me. Does the #include "process.h" essentially compile as if you had the functions and their prototypes in the main.c above the rest of the code? To me that would make the int counter global so I know I am confusing something.
Thank you for taking your time to read this.
That's a function of the executable file format, not the C language itself. For ELF (*nix and similar systems) and PE/COFF (Windows and similar), globals or other objects with static storage duration will be stored in either the .bss or .data sections depending on whether they're initialized or not. This is space allocated from within the program's binary image itself (not taken from the stack or heap).
Other executable file formats may use different section names.
In C90, can I redefine main and give it another name, and possibly add extra parameters using #define?
Have this in a header file for example:
#include <stdio.h>
#include <stdlib.h>
#define main( void ) new_main( void )
int new_main( void );
The header doesn't show any errors when compiling.
When I try compiling it with the main C file, however, I keep getting an error
In function '_start': Undefined reference to 'main'
No, you cannot do that, because it would be against language and OS standards. The name main and its arguments argc, argv and environ constitute a part of system loader calling conventions.
A bit simplifying explanation (no ABI level, just API level) ensues. When your program has been loaded into memory and is about to start, the loader needs to know which function to call as an entrypoint, and how to pass its environment to it. If it was be possible to change the name of main and/or its parameter list, it would have been needed to communicate details of new calling interface back to the loader. And there is no convenient way to do it (apart from writing your own executable loader).
In function '_start': Undefined reference to 'main'
Here you can see an implementation detail of Linux/POISX ELF loader interface. The compiler adds function _start to your program behind the scenes, which is an actual program entrypoint. _start is tasked to do extra initialization steps common to most programs that use LibC. It is _start that later calls your main. Theoretically, you could write a program that has its own function called _start and no main and it would be fine. It is not trivial as you will have to make sure that the default _start code is no longer being attached to your program (no double definitions), but it is doable. And no, you cannot choose other name than _start for the same reasons.
The presence of #define main new_main within a compilation unit will not affect the name of the function the implementation will call on program startup. The implementation is going to call a function called main regardless of any macros you define.
If you are going to use a #define like that to prevent the primary declaration of main() from producing a function by that name, you'll need to include a definition of main() somewhere else; that alternate version could then invoke the original. For example, if the original definition didn't use its arguments, and if the program exits only by returning from main() [as opposed to using exit()] you might put #define main new_main within a header file used by the primary definition of main, and then in another file do something like:
#include <stdio.h>
#include <conio.h> // For getch() function.
int main(void)
{
int result = main();
printf("\nExit code was %d. Strike any key.\n", result);
getch();
return result;
}
In most cases, it would be better to add any such code within the ordinary "main" function, but this approach can be useful in cases where the file containing main is produced by code generation tools on every build, or for some other reason cannot be modified to include such code.
No you cannot (as Grigory said).
You can however, immediate call your proxy main,
int
your_new_main(int argc, char* argv[], char* envp[]) {
... //your stuff goes here
}
//just place this in an include file, and only include in main...
int
main( int argc, char* argv[], char* envp[])
{
int result = your_new_main(argc, argv);
return result;
}
As far as whether envp is supported everywhere?
Is char *envp[] as a third argument to main() portable
Assuming you're using gcc passing -nostdlib to your program, and then set a new entry, by passing this to gcc which passing it to the linker, -Wl,-enew_main. Doing this won't give you access to any of the nice features that the C runtime does before calling your main, and you'd have to do it yourself.
You can look at resources about what happens before main is called.
What Happens Before main
I have these files
test1.h
extern int value;
void inc_value();
int print_value();
test1.c
#include "test1.h"
int value=0;
void inc_value()
{
printf("inc value from test3.c = %d\n", value++);
}
int print_value()
{
printf(" value in test1.c = %d\n", value);
return value;
}
test3.c
# include "test1.h"
main()
{
inc_value();
}
test4.c
# include <stdio.h>
#include "test1.h"
main()
{
printf("value from test4 = %d\n", print_value());
}
I'm updating variable "value" from test3.c and trying to read it from test4.c. However test3.c is unable to update the "value" that is declared in test1.h and defined in test1.c
What point am I missing here..
This will never work.
You can't use an external variable from two different programs and magically expect it to work. It's just ... wrong. Each program runs in its own address space, and doesn't know anything about any other process' address spaces. There are techniques for doing this (look up interprocess communucation), but that's a whole different area.
The way extern works is that it allows you to access a variable defined in a different C file within the same program.
You seem to be mis-understanding at a quite fundamental level how the programs you are writing work and execute, since you expect this to work. I recommend reading up more on how C works, and also perhaps a bit on how operating systems host programs in order to run them.
One way of sharing information between programs like you describe is to store the data in a file, which is written by one program (the one that runs first) and read by the other, but that is quite tricky to get right, too.
If you want to call void inc_value() from another file, you should declare it (probably in the header):
void inc_value();
If you want to directly access value, you can, as it was declared as an extern:
# include "test1.h"
main()
{
value = 6;
}
Also note, that in current implementation of inc_value, the value will be incremented after it is passed to printf, e.g. the printed value will be the previous one.
You should put extern int value in the test3.c and just put int value in test1.h.Look at this link: http://www.learncpp.com/cpp-tutorial/42-global-variables/ Hope this helps...
How to get function's name from function's pointer in C?
Edit: The real case is: I'm writing a linux kernel module and I'm calling kernel functions. Some of these functions are pointers and I want to inspect the code of that function in the kernel source. But I don't know which function it is pointing to. I thought it could be done because, when the system fails (kernel panic) it prints out in the screen the current callstack with function's names. But, I guess I was wrong... am I?
I'm surprised why everybody says it is not possible. It is possible on Linux for non-static functions.
I know at least two ways to achieve this.
There are GNU functions for backtrace printing: backtrace() and backtrace_symbols() (See man). In your case you don't need backtrace() as you already have function pointer, you just pass it to backtrace_symbols().
Example (working code):
#include <stdio.h>
#include <execinfo.h>
void foo(void) {
printf("foo\n");
}
int main(int argc, char *argv[]) {
void *funptr = &foo;
backtrace_symbols_fd(&funptr, 1, 1);
return 0;
}
Compile with gcc test.c -rdynamic
Output: ./a.out(foo+0x0)[0x8048634]
It gives you binary name, function name, pointer offset from function start and pointer value so you can parse it.
Another way is to use dladdr() (another extension), I guess print_backtrace() uses dladdr(). dladdr() returns Dl_info structure that has function name in dli_sname field. I don't provide code example here but it is obvious - see man dladdr for details.
NB! Both approaches require function to be non-static!
Well, there is one more way - use debug information using libdwarf but it would require unstripped binary and not very easy to do so I don't recommend it.
That's not directly possible without additional assistance.
You could:
maintain a table in your program mapping function pointers to names
examine the executable's symbol table, if it has one.
The latter, however, is hard, and is not portable. The method will depend on the operating system's binary format (ELF, a.out, .exe, etc), and also on any relocation done by the linker.
EDIT: Since you've now explained what your real use case is, the answer is actually not that hard. The kernel symbol table is available in /proc/kallsyms, and there's an API for accessing it:
#include <linux/kallsyms.h>
const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize,
unsigned long *ofset, char **modname, char *namebuf)
void print_symbol(const char *fmt, unsigned long addr)
For simple debug purposes the latter will probably do exactly what you need - it takes the address, formats it, and sends it to printk, or you can use printk with the %pF format specifier.
In the Linux kernel, you can use directly "%pF" format of printk !
void *func = &foo;
printk("func: %pF at address: %p\n", func, func);
The following works me on Linux:
printf the address of the function using %p
Then do an nm <program_path> | grep <address> (without the 0x prefix)
It should show you the function name.
It works only if the function in question is in the same program (not in a dynamically linked library or something).
If you can find out the load addresses of the loaded shared libraries, you can subtract the address from the printed number, and use nm on the library to find out the function name.
You can't diectly but you can implement a different approach to this problem if you want. You can make a struct pointer instead pointing to a function as well as a descriptive string you can set to whatever you want.
I also added a debugging posebilety since you problably do not want these vars to be printet forever.
// Define it like this
typedef struct
{
char *dec_text;
#ifdef _DEBUG_FUNC
void (*action)(char);
#endif
} func_Struct;
// Initialize it like this
func_Struct func[3]= {
#ifdef _DEBUG_FUNC
{"my_Set(char input)",&my_Set}};
{"my_Get(char input)",&my_Get}};
{"my_Clr(char input)",&my_Clr}};
#else
{&my_Set}};
{&my_Get}};
{&my_Clr}};
#endif
// And finally you can use it like this
func[0].action( 0x45 );
#ifdef _DEBUG_FUNC
printf("%s",func.dec_text);
#endif
There is no way how to do it in general.
If you compile the corresponding code into a DLL/Shared Library, you should be able to enlist all entry points and compare with the pointer you've got. Haven't tried it yet, but I've got some experience with DLLs/Shared Libs and would expect it to work. This could even be implemented to work cross-plarform.
Someone else mentioned already to compile with debug symbols, then you could try to find a way to analyse these from the running application, similiar to what a debugger would do.
But this is absolutely proprietary and not portable.
If the list of functions that can be pointed to is not too big or if you already suspect of a small group of functions you can print the addresses and compare them to the one used during execution. Ex:
typedef void (*simpleFP)();
typedef struct functionMETA {
simpleFP funcPtr;
char * funcName;
} functionMETA;
void f1() {/*do something*/}
void f2() {/*do something*/}
void f3() {/*do something*/}
int main()
{
void (*funPointer)() = f2; // you ignore this
funPointer(); // this is all you see
printf("f1 %p\n", f1);
printf("f2 %p\n", f2);
printf("f3 %p\n", f3);
printf("%p\n", funPointer);
// if you want to print the name
struct functionMETA arrFuncPtrs[3] = {{f1, "f1"}, {f2, "f2"} , {f3, "f3"}};
int i;
for(i=0; i<3; i++) {
if( funPointer == arrFuncPtrs[i].funcPtr )
printf("function name: %s\n", arrFuncPtrs[i].funcName);
}
}
Output:
f1 0x40051b
f2 0x400521
f3 0x400527
0x400521
function name: f2
This approach will work for static functions too.
Use kallsyms_lookup_name() to find the address of kallsyms_lookup.
Use a function pointer that points to kallsyms_lookup, to call it.
Check out Visual Leak Detector to see how they get their callstack printing working. This assumes you are using Windows, though.
Alnitak's answer is very helpful to me when I was looking for a workaround to print out function's name in kernel module. But there is one thing I want to supplyment, which is that you might want to use %pS instead of %pF to print function's name, becasue %pF not works anymore at some newer verions of kernel, for example 5.10.x.
Not exactly what the question is asking for but after reading the answers here
I though of this solution to a similar problem of mine:
/**
* search methods */
static int starts(const char *str, const char *c);
static int fuzzy(const char *str, const char *c);
int (*search_method)(const char *, const char *);
/* asign the search_method and do other stuff */
[...]
printf("The search method is %s\n", search_method == starts ? "starts" : "fuzzy")
If your program needs this a lot you could define the method names along with a string in an XMacro and use #define X(name, str) ... #undef X in the code to get the corresponding string from the function name.
You can't. The function name isn't attached to the function by the time it's compiled and linked. It's all by memory address at that point, not name.
You wouldn't know how you look like without a reflecting mirror. You'll have to use a reflection-capable language like C#.