最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Does the call instruction write something onto the stack? For example, things like environment variables? - Stack Overflow

programmeradmin1浏览0评论

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 It's not clear from your screenshots that the lower memory contents were actually altered as a side effect of this current function call. For all we know, that data has been there all along, perhaps left behind by some previous chain of calls that descended that far down the stack before returning back up. – Igor Tandetnik Commented Feb 8 at 4:23
  • 1 I am quite certain that this section of memory is being written to upon entering the function. You can focus on the purple part, which only shows the memory modified by the previous assembly instruction. – qingfu liu Commented Feb 8 at 4:36
  • @qingfu liu — You are right, without the modification of the stack memory many routine operations would be impossible. After all, one can modify the values of stack variables and actual function parameters. At the same time, it is possible to create a function not using the stack, or using only push and pop, not modifying anything on the stack itself, except the pushed data. – Sergey A Kryukov Commented Feb 8 at 5:58
  • Stack typically grows downwards and all the remaining memory below stack pointer at the time of invocation can be used by the function. – user7860670 Commented Feb 8 at 10:28
  • You only show the contents at the address 0x4201C0 (where the conspicuous text is) once. You claim it is changing, but you don't show the contents before and after whaterver moment you believe it changes at. Memory regions for which you do show before-and-after state don't appear to change in any suspicious manner; just the normal stack frame setup. – Igor Tandetnik Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 0

Of 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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论