在 glib-2.17 中,我得到了 getcontext() 汇编代码:
0x0000000000401b50 <+0>: mov %rbx,0x80(%rdi)
0x0000000000401b57 <+7>: mov %rbp,0x78(%rdi)
0x0000000000401b5b <+11>: mov %r12,0x48(%rdi)
0x0000000000401b5f <+15>: mov %r13,0x50(%rdi)
0x0000000000401b63 <+19>: mov %r14,0x58(%rdi)
0x0000000000401b67 <+23>: mov %r15,0x60(%rdi)
0x0000000000401b6b <+27>: mov %rdi,0x68(%rdi)
0x0000000000401b6f <+31>: mov %rsi,0x70(%rdi)
0x0000000000401b73 <+35>: mov %rdx,0x88(%rdi)
0x0000000000401b7a <+42>: mov %rcx,0x98(%rdi)
0x0000000000401b81 <+49>: mov %r8,0x28(%rdi)
0x0000000000401b85 <+53>: mov %r9,0x30(%rdi)
0x0000000000401b89 <+57>: mov (%rsp),%rcx
0x0000000000401b8d <+61>: mov %rcx,0xa8(%rdi)
0x0000000000401b94 <+68>: lea 0x8(%rsp),%rcx
0x0000000000401b99 <+73>: mov %rcx,0xa0(%rdi)
0x0000000000401ba0 <+80>: lea 0x1a8(%rdi),%rcx
0x0000000000401ba7 <+87>: mov %rcx,0xe0(%rdi)
0x0000000000401bae <+94>: fnstenv (%rcx)
0x0000000000401bb0 <+96>: fldenv (%rcx)
0x0000000000401bb2 <+98>: stmxcsr 0x1c0(%rdi)
0x0000000000401bb9 <+105>: lea 0x128(%rdi),%rdx
0x0000000000401bc0 <+112>: xor %esi,%esi
0x0000000000401bc2 <+114>: xor %edi,%edi
0x0000000000401bc4 <+116>: mov $0x8,%r10d
0x0000000000401bca <+122>: mov $0xe,%eax
0x0000000000401bcf <+127>: syscall
0x0000000000401bd1 <+129>: cmp $0xfffffffffffff001,%rax
0x0000000000401bd7 <+135>: jae 0x410f70 <__syscall_error>
0x0000000000401bdd <+141>: xor %eax,%eax
0x0000000000401bdf <+143>: retq
似乎只有 uc_mcontext 在 getcontext() 调用中被修改。uc_stack 保持不变。
通过阅读 getcontext info,得到以下单词:
Unix 标准提供了一组函数来控制执行路径,这些函数比本章迄今为止讨论的函数更强大。这些函数是原始 System V API 的一部分,并通过此路径添加到 Unix API。除了品牌的 Unix 实现之外,这些接口并不广泛可用。并非 GNU C 库的所有平台和/或体系结构都提供此接口。使用“配置”来检测可用性。
而 man getcontext 有以下几句话:
符合 SUSv2,POSIX.1-2001。POSIX.1-2008 删除了 getcontext() 的规范,引用了可移植性问题,并建议重写应用程序以改用 POSIX 线程。
所以我认为 getcontext/setcontext/swapcontext/makecontext 都是过时的,应该避免使用。