I was wondering if there is a function in C (let's dub it int get_stack_depth()), which returns the amount of functions currently being executed on the stack. For example:
int foo(){
return get_stack_depth();
}
int bar2(){
return get_stack_depth();
}
int bar1(){
return bar2();
}
int bar(){
return bar1();
}
int main(){
get_stack_depth(); // = 0
foo(); // = 1
bar(); // = 3
return 0;
}
I would like to use it for debugging info, where each printf would contain get_stack_depth() indents to increase readability. If this is compiler dependent, or anything-else dependent, I take all the constraints; right now I wonder whether this is supported at least somewhere.
EDIT: The answer at the suggested duplicate didn't help me at all, as the accepted answer here suggests, you cannot determine how many functions are on the stack based purely upon the size of the stack; the information is simply not there.
The exact mechanics of the stack in C are implementation-specific, so there is no single, correct, standard way to find the depth of the stack. There are some methods to simulate this behavior, though.
Use a counter. Define a global unsigned depth, and in each function in which you care about the depth of the stack, inject depth++ at the beginning and depth-- at the end. This is obviously the more tedious method, and it's prone to a lot of frustrating issues if an increment or decrement is left off.
Check the stack pointer. On x86 systems (virtually every desktop & laptop device), the stack grows downward, meaning that entering a function call will decrease the value of the stack pointer. In many cases (but not all, e.g. when optimization is enabled) the stack pointer register, %rsp, points to the "top" of the current function's stack frame. A rather hacky way to fetch this value is to assign it to a variable: register uint64_t rsp asm ("rsp");. The lower the value, the greater the depth on the stack.
Unfortunately, the size of the decrement between function calls depends on how large the stack frame for that function is—if one function declares a large array as a local variable, then the stack pointer will be much lower for functions it calls, since more space is consumed by the array.
Ultimately the only reliable way I know of to find an accurate backtrace of function calls is to run the program in a debugger such as gdb and issue the backtrace command, which will print the current call stack. This kind of support just doesn't seem to be available to the program when it is run independent of any debugger.
Have you tried using backtrace()?
for example:
#include <execinfo.h>
unsighed int getDepth(){
const unsigned int max_depth = 200;
void* buffer[max_depth];
return backtrace(buffer, max_depth)-5;
}
The -5 is there because there are some functions above main (added by the libc) that I want to ignore. However, if you want to calculate that automatically, change my function to
int get_stack_depth(int set_caller_as_root){
static int root_depth = 0;
if (set_caller_as_root){
root_depth = get_stack_depth(0) - 1;
}
const int max_depth = 200;
void* buffer[max_depth];
return backtrace(buffer, max_depth) - root_depth;
}
and update your code to
int foo(){
return get_stack_depth(0);
}
int bar2(){
return get_stack_depth(0);
}
int bar1(){
return bar2();
}
int bar(){
return bar1();
}
int main(){
printf("%d\n", get_stack_depth(1)); // = 0
printf("%d\n", foo()); // = 1
printf("%d\n", bar()); // = 3
return 0;
}
which yields the correct, expected results.
Note that execinfo.h is not installed on windows 10 by default (it is on linux).
Related
I have a function like this
void abc()
{
printf("hello\n");
}
lets suppose I checked and know that the address of above function say 0x08000040 now if I assign it to function pointer in main like this
int main()
{
void (*p)()=(void *)0x08000040;
p();// and call it like
return 0;
}
will it call some how. I tried it does not work but suppose I have function in the same program then will it work after I some how found out the address of the function?
and also is this possible
to assign specific fixed address to some function in current C program
is it possible to export a function address (of abc()) in current program and so other programs can call the function in this program to call above abc() function with address hex values. it happens in kernel with exporting of sys-calls and gdb also does this with trap-handlers. So is there any easy way to make it work.
This works for me:
#include <stdio.h>
#include <stdlib.h>
void abc(void) {
puts("abc");
}
void cba(void) {
puts("cba");
}
int main(void) {
printf("type %p or %p\n", (void*)abc, (void*)cba);
char buf[100];
fgets(buf, sizeof buf, stdin);
long unsigned u = strtoul(buf + 2, NULL, 16); // ignore 0x
void (*p)(void) = (void(*)(void))u; // UB!
p(); // and call it
return 0;
}
The virtual address where a given function is located in memory is entirely implementation defined and further depends on many factors:
it is almost always different for different programs ;
it may change if you modify the program source code and recompile it ;
it may even change each time you execute the same program: modern systems perform address space randomisation in order to reduce vulnerability to certain classes of attacks. The same applies to the stack address.
Do not rely on the address values you observe in the debugger, they are likely to be different the next time you debug the program.
I would like a hint on how to complete this puzzle. I need to be able to print what is normally printed out in reverse. Normally this prints, hello there. I need it to print there hello. I am only allowed to add code where it is commented.
Here are some of my thoughts that don't work.
I thought about using the heap to store some data but I can't because stdlib.h is not included.
Can't use goto because I can't add labels and what I would goto is all in one line
Can't use recursion because there are no input parameters and no global variables to modify.
Can't possibly think of a way assembly could help but hey maybe?
I can't do anything obvious like just calling printf's and quitting the program early.
Thoughts on something to do with function pointers? I still don't see how they would help.
#include <stdio.h>
void f1(); void f2(); void f3();
int main() { f1(); printf("\n"); return 0; }
void f1() { f2(); printf(" there "); }
void f2() { f3(); printf(" hello "); }
void f3(){
int x;
//Can add whatever under here
}
I think the only purpose of int x; is to get the stack pointer without using inline assembly.
The solution on how to do this exactly will depend on your platform, the compiler you use and the optimization levels you have used.
I would say first you need to analyze the call stack.
You can do this -
int i;
for (i = 0; i< 10; i++) {
printf ("%p\n", *(void**)((char*) &x - i * 8)); // I am assumming 64 bit machines. If 32 bit replace 8 with 4
}
This will give you the top 10 8 byte values on the stack. Now you need to find the two that look like return addresses. One way to recognize them would be to print the function pointer value of f1 and f2 and see the values close to them.
You now know the indexes where they are stored. Just go ahead and swap them.
For swapping them, say the indices are 12 and 14.
Then you can do this -
*(void**)&x = *((void**)&x + 12);
*((void**)&x + 12) = *((void**)&x + 14);
*((void**)&x + 14) = *(void**)&x;
Also make sure you don't change the stack layout once you get the indices. This means don't remove/add any variables. Don't apply the & operator to any new variables (or remove from any) and don't remove any function calls.
Also another suggestion - Instead of using int x, you could declare another unsigned long long y and use that for the swap instead. Because it would have enough bytes to hold a pointer (on 64 bit machines). Usually there will be padding in case of int x too which should save you from the problem but rather be safe.
Here's an alternate solution that doesn't depend on stack manipulation. The fundamental 'trick' is that the program provides its own implementation of printf() instead of using the standard library's.
Tested on gcc (Mingw, Linux x86 and Linux x64) and MSVC:
#include <stdio.h>
void f1(); void f2(); void f3();
int main() { f1(); printf("\n"); return 0; }
void f1() { f2(); printf(" there "); }
void f2() { f3(); printf(" hello "); }
void f3(){
int x;
//Can add whatever under here
return;
}
void putstr( char const* s)
{
for (;*s;++s) {
putchar(*s);
}
}
int printf(char const* fmt, ...)
{
static char const* pushed_fmt = 0;
if (*fmt == '\n') {
putstr(fmt);
return 0;
}
if (pushed_fmt == 0) {
pushed_fmt = fmt;
return 0;
}
putstr(fmt);
putstr(pushed_fmt);
return 0;
}
I think the idea is that from f3() you have the return addresses on the stack all the way up, and nothing has been printed so far.
You'd have to play with the stack contents so that f3() returns into f1(), which would then return into f2().
Can you take it from here? Depending on the compiler, there will be different ways to accomplish this. Inline assembly might or might not be required.
EDIT: specifically for GCC, see the GCC return address intrinsics.
This should be a portable solution that doesn't mess with the stack and return addresses. Most probably not what was expected by who wrote that challenge, but it's way more fun to think out of the box.
void f3(){
int x;
//Can add whatever under here
static count = 0;
static char buf[256];
if(count==0) {
setvbuf(stdout, buf, _IOFBF, sizeof(buf));
int atexit (void (*func)(void));
atexit(f3);
count = 1;
} else {
const char *src = " there hello \n";
char *dest = buf;
for(; *src;) *dest++ = *src++;
}
}
http://ideone.com/S4zMHP
This works by first using setvbuf to replace the stdout buffer with one that we provide, and switching it to full buffering (instead of line buffering) to make sure that no flush happens before the end of the program (notice that no output has been written yet, so calling setvbuf is legal). We also call atexit to make sure we get called before the end of the program (we don't have stdlib.h, but who needs headers when the required prototypes are already known).
When we are called again (thanks to atexit), the two printf have been called, but the buffer hasn't been flushed yet. We outright replace its content with the string of our interest (which is just as big as what has been written), and return. The subsequent implicit fclose will dump out the modified content of our buffer instead of what was written by the printf.
Thinking about returning dynamic or automatic arrays. Not really C-related.
The usual technique to return an array is: A) callee allocates on heap and returns, B) caller allocates on stack and passes to callee.
// A
void caller(void) {
int *a = callee();
free(a);
}
int *callee(void) {
int *a = malloc(10 * sizeof(*a));
return a;
}
// B
void caller(void) {
int a[10]; callee(a, sizeof(a) / sizeof(a[0]));
}
void callee(int *a, size_t n) {
//
}
Case A may lead to unnecessary allocate-free cycle, while case B requires syntactic garbage in caller. In B we also can't compute n in callee, because it comes predefined. We also can't return automatic storage because it will be destroyed on return (accessing it is UB in general).
But what if we introduce new return_auto operator that will return from callee, but leave it's stack frame intact, as if caller did all the job on it's own stack?
// C
void caller(void) {
int *a = callee();
}
int *callee() {
int a[compute_n()];
return_auto a;
}
I mean, caller could inherit callee's stack frame and all issues disappear. It's stack frame would look like this after return_auto:
[caller frame]
arguments
ret-pointer
locals
int *a = callee.a
[callee frame] (defunct)
arguments
ret-pointer
locals
int a[n] (still alive)
[end-of-callee-frame]
[end-of-caller-frame]
In machine code (x86 at least) this may be implemented by jumping to ret-pointer at ss:ebp instead of mov esp, ebp / ret n. We already have VLAs in modern C, and this looks very similar but slightly complex.
Of course that should be used with care, because series of return_auto's would leave pretty huge dump on stack, that will be "collected" only when outermost caller returns (normally). But stack allocations are insanely cheap, and in theory some algorithms could benefit from not calling malloc/free at all. This is also interesting in code structuring perspective, not just performance.
Does anyone know where this technique is implemented / stack frames joined?
(C is just an example here)
Okay, it needs a simple example.
void caller(Context *ct) {
char *s = make_s(ct);
printf("%s\n", s);
}
void make_s(Context *ct) {
const char *tag = "?", *name = "*";
if (ct->use_tag) tag = ct->tag;
else if (ct->app) tag = ct->app->tag;
if (ct->app) name = ct->app->name;
char s[strlen(tag)+strlen(name)+10];
snprintf(s, len, "%s.object(%s)", name, tag);
return_auto s;
}
Obviously, for now we need to explode that in caller's body (probably via macro to feel all caveats) or do asprintf/malloc in callee and free in caller.
This seems a very bad idea for any non-trivial scenario. Just remember a stack frame contains all the local variables along with return address, saved base pointer, and so on. In your model, a caller would need to "inherit" the whole frame as part of its own frame. Then think about you might pass this returned value to some OTHER function. So what if this function wants to return more than just an integral value? You would easily end up with a huge stack frame for main(). Any heap implementation is probably more space efficient.
How can I save (and restore) the stack and the heap of a program at a specific point in the program?
Consider a program like this:
int main()
{
int a;
int *b;
b = (int*)malloc(sizeof(int))
a = 1;
*b = 2;
save_stack_and_heap(); // looking for this...
a = 3;
*b = 4;
restore_stack_and_heap() // ... and this
printf("%d %d\n",a,*b);
return 0;
}
The output should be:
1 2
It boils down to (am I right?): How do I get the pointers to the stack and to the heap and their sizes?
edit
I want to use this for a number of things. One of them is to write code that can handle hardware failure by checkpointing and being able to restart at a checkpointed state.
Let's focus on the stack, as heap allocations can be tracked otherwise (good old malloc preload for instance).
The code should be reusable. There can be any possible number and type of variables on the stack.
The best would be standard C99. Next best Posix conform. Next best Linux conform.
I am usually using GCC but I would prefer not to use built ins...
int main()
{
int a = 1;
int *b = malloc(sizeof(int));
*b = 2;
if (fork() == 0) {
a = 3;
*b = 4;
return 0;
}
int status;
wait(&status);
printf("%d %d\n",a,*b);
return 0;
}
So you haven't given a lot of scope of what you are trying to achieve but I will try and tackle a few perspectives and at least something that can get you started.
It boils down to (am I right?): How do I get the pointers to the stack
and to the heap and their sizes?
The stack is a large thing, and often expandable in size. I'm going to skip the heap bit as you are going to struggle to save all the heaps (that kinda doesn't make any sense). Getting a pointer to the stack is as easy as declaring a variable and taking a reference to it like so.
int a = 5;
void *stack_ptr = &a;
void *another_stack_ptr = &stack_ptr;
// We could could go on forever with this....
That is not the base address of the stack however. If you want to find that there may be many methods, and even API's (I think there is on Windows). You can even just walk in both directions from an address on the stack until you get a page fault. That is likely to mark the beginning and end of the stack. The following might work, no guarantees. You will need to set up an exception handler to handle the page fault so your app doesn't crash.
int variable = 5;
int *stack_start = &variable;
int *stack_end = stack_start;
int *last_good_address = NULL;
// Setup an exception handler
...
// Try accessing addresses lower than the variable address
for(;;)
{
int try_read = stack_start[0];
// The read didn't trigger an exception, so store the address
last_good_address = stack_start
stack_start--;
}
// Catch exception
... stack_start = last_good_address
// Setup an exception handler
...
// Try accessing addresses higher than the variable address
for(;;)
{
int try_read = stack_end[0];
// The read didn't trigger an exception, so store the address
last_good_address = stack_end
stack_end--;
}
// Catch exception
... stack_end = last_good_address
So if you have the base and end address of the stack you can now memcpy it into some memory (I'd advise against the stack though!).
If you just want to copy a few variables, because copying the entire stack would be crazy, the conventional method would be to save them prior to a call
int a = 5;
int b = 6;
int c = 7;
// save old values
int a_old = a;
int b_old = b;
int c_old = c;
some_call(&a, &b, &c);
// do whatever with old values
I'll assume that you have written a function that has 10,000 variables on the stack, and you don't want to have to save them all manually. The following should work in this case. It uses _AddressOfReturnAddress to get the highest possible address for the current functions stack and allocates some stack memory to get the lowest current value. It then copies everything in between.
Disclaimer: This has not been compiled, and is unlikely to work out of the box, but I believe the theory is sound.
// Get the address of the return address, this is the highest address in the current stack frame.
// If you over-write this you are in trouble
char *end_of_function_stack = _AddressOfReturnAddress();
// Allocate some fresh memory on the stack
char *start_of_function_stack = alloca(16);
// Calculate the difference between our freshly allocated memory and the address of the return address
// Remember to subtract the size of our allocation from this to not include it in the stack size.
ptrdiff_t stack_size = (end_of_function_stack - start_of_function_stack) - 16);
// Calculation should not be negative
assert(stack_size > 0)
// Allocate some memory to save stack variables
void *save_the_stack = malloc(stack_size);
// Copy the variables
memcpy(save_the_stack, &start_of_function_stack[16], stack_size);
That's about all I can offer you with the limited information in your question.
I think you're looking to reuse the variable names a and b in this case? You should declare new variable of the same name on different scope!
int main()
{
int a=1;
int *b = (int*)malloc(sizeof(int));
*b=2;
{
int a=3;
int *b = (int*)malloc(sizeof(int));
*b=4
}//beware, other lang such as C# may persist stack variables after this point
//old a,b should be reachable here
}
I am writing the following code that will be able to change the stack of function call. but it always runs into segfault on printf. I debugged the code with assembly, the stack was successfully switched. it is the printf statement that created the segfault and not sure the reason. anybody has any clue what direction i should look into more?
Thanks.
char stack[4000000*4];
void foo(int ad) {
int i = 100;
int sum = i*i + ad;
printf("stack changed to %X\n", stack);
}
/* in this example, foo (and its decendents) live on a new stack */
void change_stack(void *newstack) {
void *ctx[5]; // Jump buffer for setjmp/longjmp.
if (0 == __builtin_longjmp(ctx)) {
ctx[2] = newstack; // switch stack
__builtin_longjmp(ctx, 1);/* here stack is switched */
} else {
/* now live on new stack, can we pass parameters now ? */
int ad = 20;
foo(ad);
}
}
int main (int argc, char** argv)
{
int i = 10;
change_stack(stack);
printf("return, %d\n", i);
return 0;
}
You switch stacks without copying the contents of the old one. When change_stack returns, the results are undefined (it may, for example, jump to address NULL, causing a segfault). Also, things like local variables will also be undefined.
Also, (assuming we're talking x86 here), the stack pointer is decremented on pushes. Since the new stack pointer you assigned is the base (i.e. lowest) address of your stack array, any push will decrease the pointer outside of this array, also possibly resulting in a segfault.
To anyone who still wants to play with the stack and also encountered SIGSEGV in printf, here is an important point:
You can find one of the subroutines of printf, __GI___tcgetattr under /path-to-glibc/sysdeps/unix/sysv/linux/tcgetattr.c. There is one instrution in it:
movdqa (%rsp),%xmm0
And according to this answer, it reads 16-byte align memory from source address. So you should keep the address of %rsp at least 16-byte address align when you switch the stack, otherwise you will get a SIGSEGV.