I am currently running a C++ program in which I have used the heap to simulate the stack and employed assembly language to place relevant information (such as memory addresses) into registers, thereby achieving coroutine switching. However, after switching to the new stack, I have noticed that the stack memory is unexpectedly altered when functions are called.
Before a function is called, the gdb information is as follows:
(gdb) info frame
Stack level 0, frame at 0x420520:
rip = 0x7ffff7eaf3b6 in clsn::Coroutine::CoroutineFunc (/data/workspace/DeftRPC/src/coroutine/Coroutine.cpp:16); saved rip = 0x0
called by frame at 0x420528
source language c++.
Arglist at 0x420510, args: arg=0x41ffd0
Locals at 0x420510, Previous frame's sp is 0x420520
Saved registers:
rbp at 0x420510, rip at 0x420518
The memory near RIP(0x420518) is as follows,the green area indicates the location of the RIP:
After a function is called, the gdb information is as follows:
(gdb) info frame
Stack level 0, frame at 0x4204f0:
rip = 0x7ffff7eaf436 in clsn::Coroutine::operator() (/data/workspace/DeftRPC/src/coroutine/Coroutine.cpp:32); saved rip = 0x7ffff7eaf3c2
called by frame at 0x420520
source language c++.
Arglist at 0x4204e0, args: this=0x41ffd0
Locals at 0x4204e0, Previous frame's sp is 0x4204f0
Saved registers:
rbp at 0x4204e0, rip at 0x4204e8
It can be observed that the RIP has moved several bytes towards the lower address, which is normal behavior.
Now,the memory near RIP(0x4204e8) is as follows,the green area indicates the location of the RIP,the blue area represents the previous location of the RIP, and the purple area signifies that the memory has been altered: 。
So far, all the behavior is normal.
However, I have noticed that at addresses lower than the current RIP, my stack memory has been altered. I am not entirely sure what is causing this behavior (it seems that either GCC or the operating system has written something there), but this behavior is affecting my program. I would like to understand why it is happening. What is happening in memory is illustrated in the figure below, where the colors in the diagram represent the meanings described above. At the moment, I only know that among the things written, there is the directory in which my program is running. Can someone help me analyze what is happening?
I am currently running a C++ program in which I have used the heap to simulate the stack and employed assembly language to place relevant information (such as memory addresses) into registers, thereby achieving coroutine switching. However, after switching to the new stack, I have noticed that the stack memory is unexpectedly altered when functions are called.
Before a function is called, the gdb information is as follows:
(gdb) info frame
Stack level 0, frame at 0x420520:
rip = 0x7ffff7eaf3b6 in clsn::Coroutine::CoroutineFunc (/data/workspace/DeftRPC/src/coroutine/Coroutine.cpp:16); saved rip = 0x0
called by frame at 0x420528
source language c++.
Arglist at 0x420510, args: arg=0x41ffd0
Locals at 0x420510, Previous frame's sp is 0x420520
Saved registers:
rbp at 0x420510, rip at 0x420518
The memory near RIP(0x420518) is as follows,the green area indicates the location of the RIP:
After a function is called, the gdb information is as follows:
(gdb) info frame
Stack level 0, frame at 0x4204f0:
rip = 0x7ffff7eaf436 in clsn::Coroutine::operator() (/data/workspace/DeftRPC/src/coroutine/Coroutine.cpp:32); saved rip = 0x7ffff7eaf3c2
called by frame at 0x420520
source language c++.
Arglist at 0x4204e0, args: this=0x41ffd0
Locals at 0x4204e0, Previous frame's sp is 0x4204f0
Saved registers:
rbp at 0x4204e0, rip at 0x4204e8
It can be observed that the RIP has moved several bytes towards the lower address, which is normal behavior.
Now,the memory near RIP(0x4204e8) is as follows,the green area indicates the location of the RIP,the blue area represents the previous location of the RIP, and the purple area signifies that the memory has been altered: 。
So far, all the behavior is normal.
However, I have noticed that at addresses lower than the current RIP, my stack memory has been altered. I am not entirely sure what is causing this behavior (it seems that either GCC or the operating system has written something there), but this behavior is affecting my program. I would like to understand why it is happening. What is happening in memory is illustrated in the figure below, where the colors in the diagram represent the meanings described above. At the moment, I only know that among the things written, there is the directory in which my program is running. Can someone help me analyze what is happening?
Share Improve this question asked Feb 8 at 3:56 qingfu liuqingfu liu 372 bronze badges 5 |1 Answer
Reset to default 0Of course, stack memory is modified! How else? The particular behavior depends on calling conventions
.
First and foremost, stack memory is the place where the actual function parameters are placed.
Besides, the calling function use stack memory for storing stack variables. During the call, the space for these variables is allocated on stack. It is possible, because the required memory size for these variables and the shift of each variable relative to the stack frame is statically known to the compiler.
The values of the function parameters and stack variables can be modified several times by the execution of the function body.
At the same time, it is possible to create a function not using stack at all, the only piece of data pushed on stack being a return address. Everything else can be processed in registers. Similarly, some other functions may not modify anything on the stack memory, except data pushed on the stack using only push
(eventually balanced by pop
).
All this stuff has nothing to do with environment variables. The access to an environment variable is a matter of the platform API. That is, basically, it is a call.
You are using an interesting technique of the experiments with the stack. Indeed, you can point to any piece of the memory accessed by the process by the stack pointer. However, it is also possible to examine the content of the stack, created by the system loader in a usual way. You can analyze it as a piece of raw memory.
push
andpop
, not modifying anything on the stack itself, except the pushed data. – Sergey A Kryukov Commented Feb 8 at 5:58