user-0 提问: 分享奇异BUG一枚

回复:
user: user-1
content: 楼主很牛逼！

user: user-0
content: 引用 50 楼 bug1190 的回复:一个SB在这B叫而己 Remarks The GetThreadContext function is used to retrieve the context of the specified thread. The function allows a selective context to be retrieved based on the value of the ContextFlags member of the CONTEXT structure. The thread handle identified by the hThread parameter is typically being debugged, but the function can also operate when it is not being debugged.  You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.  If you call GetThreadContext for the current thread, the function returns successfully; however, the context returned is not valid.  像你这种没教养的东西，我不愿意理你，自己滚蛋。

user: user-0
content: 引用 45 楼 fly_dragon_fly 的回复:int  getcontext( ucontext_t *a ) {       int ret;       a->thread_context.ContextFlags = CONTEXT_FULL;       ret = GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1;       return ret; }  这个ret会导致占用栈空间4字节，而set的时候没有这个消耗，当切换回来a时，两边栈就不平衡，导致返回地址无效了。  这是正确答案。  这位兄弟肯定搞过类似的工作吧？

user: user-2
content: 楼上的分析很精辟。

user: user-3
content: int  getcontext( ucontext_t *a ) {       int ret;       a->thread_context.ContextFlags = CONTEXT_FULL;       ret = GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1;       return ret; }  这个ret会导致占用栈空间4字节，而set的时候没有这个消耗，当切换回来a时，两边栈就不平衡，导致返回地址无效了。

user: user-4
content: 难道是  多进程？无限刷内存？。。

user: user-5
content: You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.  If you call GetThreadContext for the current thread, the function returns successfully; however, the context returned is not valid. 是你说可以不停就可以切换是吧，MSDN上的这段话怎么跟你说的完全相反呢

user: user-6
content: 只看看状况和分析

user: user-7
content: #include <windows.h>   typedef struct ucontext {        CONTEXT  thread_context; } ucontext_t;   int  getcontext( ucontext_t *a ) {       int ret;       a->thread_context.ContextFlags = CONTEXT_FULL;               ret = GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1; //GetThreadContext 获取的是此处的上下文，不是调用 getcontext 的调用点的上下文，切换回来以后，这部分//GetThreadContext有可能重新执行，或者在  //GetThreadContext 函数内部某点执行。        return ret; }   int setcontext( ucontext_t *a ) {       return SetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1; }   int swapcontext( ucontext_t *a, ucontext_t *b ) {       int ret;       if((ret = getcontext(a)) == 0)             ret = setcontext(b);       return ret; }  int  swapcontext( ucontext_t *a, ucontext_t *b ) {     int ret;     a->thread_context.ContextFlags = CONTEXT_FULL;     if( (ret = (GetThreadContext(GetCurrentThread(), &a->thread_context) ? 0 : -1) == 0 )           ret = SetThreadContext(GetCurrentThread(), &b->thread_context) ? 0 : -1;  //切换点在这个函数内部执行     return ret; }

user: user-8
content: 看 了半天回复，也不懂。。。

user: user-9
content: 我猜GetCurrentThread()的值有问题

user: user-10
content: 来围观，只做过多线程的初级应用。。。。

user: user-11
content: 围观的~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

user: user-12
content: 你对当前线程SetThreadContext，那么可能会影响到当前线程的执行栈，下一条语句都不知道去哪了，因此可能出现各种奇异情况：  if （ＳｅｔＴｈｒｅａｄＣｏｎｔｅｘｔ（当前线程）） ｛ 　　　在这里写代码很可能是没有任何意义的 ｝  －－－ ＳｅｔＴｈｒｅａｄＣｏｎｔｅｘｔ一般都是用来搞其他线程的，搞自己的时候真不多

user: user-13
content: 引用 30 楼 sinservice 的回复:[quote=引用 28 楼 zhao4zhong1 的回复:] 《30天自制操作系统》  在linus之前，全世界只有5个人独自设计并实现了操作系统，linus是第6个。  我根本不相信这种自制操作系统的说法。  我用8051汇编写个电子秤的程序，那的确是运行在纯粹硬件上的直接接触硬件的软件，但我不认为那就是操作系统。  [/quote] 你的成见阻挡了你学习提高的前路。 搜“空杯心态”

user: user-0
content: 引用 38 楼 luciferisnotsatan 的回复:windows不有个协程么？CreateFiberEx  不能满足lz需求？  windows fiber限制很大，最多只能建立2000多个，太少了，不够用的。

user: user-14
content: windows不有个协程么？CreateFiberEx  不能满足lz需求？

user: user-0
content: 引用 36 楼 fly_dragon_fly 的回复:ret = setcontext(b);  在切换线程后，这个context是否把当前的esp也换掉了，导致ret的地址无效了，  有门了，但不对。  你看29L，那样写就可以。

user: user-3
content: ret = setcontext(b);  在切换线程后，这个context是否把当前的esp也换掉了，导致ret的地址无效了，

user: user-15
content: getcontext setcontext 用这两个函数都是从主线程的栈中调用GetThreadContext、SetThreadContext。返回的时候作为协程会不会。。。不知道！~~~