简体   繁体   English

提升上下文实现

[英]Boost Context implementation

I'm reading the implementation of boost fcontext. 我正在阅读boost fcontext的实现。

The function prototype of make_fcontext is typedef void* fcontext_t; fcontext_t BOOST_CONTEXT_CALLDECL make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) ); make_fcontext的函数原型为typedef void* fcontext_t; fcontext_t BOOST_CONTEXT_CALLDECL make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) ); typedef void* fcontext_t; fcontext_t BOOST_CONTEXT_CALLDECL make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) );

The first argument is top of context-stack, an example from boost document is as follows: 第一个参数是上下文堆栈的顶部,boost文档中的示例如下:

// context-function
void f(intptr);


// creates a new stack
std::size_t size = 8192;
void* sp(std::malloc(size));

// context fc uses f() as context function
// fcontext_t is placed on top of context stack
// a pointer to fcontext_t is returned
fcontext_t fc(make_fcontext(sp,size,f));

When I'm reading the implementation of make_context in i386_elf, the implementation always decrease the sp, it will make the context store in the memory before sp, which is out of memory from malloc. 当我在i386_elf中读取make_context的实现时,该实现总是减少sp,它将使上下文存储在sp之前的内存中,而该内存在malloc的内存之外。 Could it overwrite the memroy not belong to the coroutine? 可以覆盖不属于协程的存储器吗?

/* first arg of make_fcontext() == top of context-stack */
movl  0x4(%esp), %eax

/*decrease the adress of sp here*/
/* reserve space for first argument of context-function
   rax might already point to a 16byte border */
leal  -0x8(%eax), %eax

/* shift address in EAX to lower 16 byte boundary */
andl  $-16, %eax

/* reserve space for context-data on context-stack */
/* size for fc_mxcsr .. EIP + return-address for context-function */
/* on context-function entry: (ESP -0x4) % 8 == 0 */
leal  -0x20(%eax), %eax

/* third arg of make_fcontext() == address of context-function */
movl  0xc(%esp), %edx
movl  %edx, 0x18(%eax)

/* save MMX control- and status-word */
stmxcsr  (%eax)
/* save x87 control-word */
fnstcw  0x4(%eax)

Depending on your CPU architecture, the stack might grow upwards (towards higher addresses) or downwards (towards lower addresses, as is the case on x86). 根据您的CPU体系结构,堆栈可能向上 (朝着更高的地址)或向下 (朝着更低的地址,例如x86)增长。 This is generally hard-coded in the instruction set by the way the push and pop instructions modify the stack pointer. 通常,这是通过pushpop指令修改堆栈指针的方式硬编码在指令集中的。 For example, the x86 push instruction subtracts from [er]?sp . 例如,x86 push指令从[er]?sp减去。

make_fcontext expects the stack pointer to have sufficient space in the architecture-specific direction needed by the platform. make_fcontext期望堆栈指针在平台所需的特定于体系结构的方向上具有足够的空间。 On x86, this means there must be available space before the pointer, not after. 在x86上,这意味着指针之前必须有可用空间,而不是在之后。 By passing the pointer you received from malloc directly, you are violating this contract. 通过直接传递从malloc收到的指针,就违反了此合同。

This is why the stack_allocator abstractions exists. 这就是为什么stack_allocator抽象存在的原因。 They return pointers that point to the right end of the stack, depending on the architecture. 它们根据架构返回指向堆栈右端的指针。

(As a side note, I believe all architectures currently supported by Boost.Context have downwards-growing stacks.) (作为一个旁注,我相信Boost.Context当前支持的所有体系结构都有向下增长的堆栈。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM