Open turbin opened 5 years ago
遇到同样的问题,coroutine_resume(S,co1) 调用 getcontext 这个函数时会修改 co2 里的内容,我猜测 macOS 里定义了不同的 ucontext_t,占用的内存更大,转换的过程中访问越界了。
ok. 搞懂了。
首先,应该引入 #include
其次,swapcontext 在 macOS 系统中的实现依赖于在栈上的返回地址,在调用 swapcontext 之前保存栈的信息会导致死循环。
这里是我修改后可以跑通的代码(在同一个函数里保存和 swap 就行了): https://gist.github.com/Jeswang/4ae2b612f0c2da20265d1d6407b6cd2b
. @Jeswang 测试了一下,发现你的修改还是有问题,例子程序里有一句
printf("main end\n");
打印程序结束的信息,但是程序没有走到这里,说明中途出错了。整个程序的输出如下,供你参考。
coroutine % vi test.c
coroutine % gcc test.c -o test
test.c:74:8: warning: 'getcontext' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
ret = getcontext(oucp);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ucontext.h:38:6: note: 'getcontext' has been explicitly marked deprecated here
int getcontext(ucontext_t *);
^
test.c:80:9: warning: 'setcontext' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
ret = setcontext(ucp);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ucontext.h:44:6: note: 'setcontext' has been explicitly marked deprecated here
int setcontext(const ucontext_t *);
^
test.c:111:8: warning: 'getcontext' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
ret = getcontext(oucp);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ucontext.h:38:6: note: 'getcontext' has been explicitly marked deprecated here
int getcontext(ucontext_t *);
^
test.c:117:9: warning: 'setcontext' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
ret = setcontext(ucp);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ucontext.h:44:6: note: 'setcontext' has been explicitly marked deprecated here
int setcontext(const ucontext_t *);
^
test.c:216:3: warning: 'getcontext' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
getcontext(&C->ctx);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ucontext.h:38:6: note: 'getcontext' has been explicitly marked deprecated here
int getcontext(ucontext_t *);
^
test.c:223:3: warning: 'makecontext' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
makecontext(&C->ctx, (void (*)(void)) mainfunc, 2, (uint32_t)ptr, (uint32_t)(ptr>>32));
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ucontext.h:41:6: note: 'makecontext' has been explicitly marked deprecated here
void makecontext(ucontext_t *, void (*)(), int, ...);
^
6 warnings generated.
coroutine % ./test
main start
coroutine 0 : 0
coroutine 1 : 100
coroutine 0 : 1
coroutine 1 : 101
coroutine 0 : 2
coroutine 1 : 102
coroutine 0 : 3
coroutine 1 : 103
coroutine 0 : 4
coroutine 1 : 104
coroutine %
在苹果的源代码里没看出所以然来。
https://github.com/Apple-FOSS-Mirror/Libc/blob/master/x86_64/gen/swapcontext.c
Mac OS 10.14.7版本。 gcc info: Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 Apple LLVM version 10.0.1 (clang-1001.0.46.4) Target: x86_64-apple-darwin18.2.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin
在这个版本上编译,并运行代码生成的main 以后程序报告:
Assertion failed: (0), function coroutine_resume, file coroutine.c, line 155. 然后通过跟踪发现,main.c 里面
发现一个问题, struct coroutine 这个结构体的成员 ud 在程序resume coroutine的 co2的时候被修改了。
any idea for this?