分享奇异BUG一枚

「已注销」 2014-12-19 02:04:43
最近本人搞了搞用户线程(协程),出现了一个奇异错误,当然,错误已经排除。

但因为它很隐晦,跟大家分享一下。凡试猜者都有分,第一个猜中谜底者得100分,其他分均分。


#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;
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;
}


PS:
1. BUG就在这些代码里,而不是在别处。
2. 如果有笔误,是可能的,因为代码是我刚打的,不是工程里的真实代码,仅为说明问题。

...全文
1242 55 打赏 收藏 转发到动态 举报
写回复
用AI写文章
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
qwer_boo 2014-12-22
  • 打赏
  • 举报
回复
楼主很牛逼!
「已注销」 2014-12-21
  • 打赏
  • 举报
回复
引用 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.
像你这种没教养的东西,我不愿意理你,自己滚蛋。
「已注销」 2014-12-21
  • 打赏
  • 举报
回复
引用 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时,两边栈就不平衡,导致返回地址无效了。
这是正确答案。 这位兄弟肯定搞过类似的工作吧?
w74839520 2014-12-20
  • 打赏
  • 举报
回复
楼上的分析很精辟。
fly_dragon_fly 2014-12-20
  • 打赏
  • 举报
回复
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时,两边栈就不平衡,导致返回地址无效了。
loong0306 2014-12-20
  • 打赏
  • 举报
回复
难道是 多进程?无限刷内存?。。
huanglin03 2014-12-20
  • 打赏
  • 举报
回复
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上的这段话怎么跟你说的完全相反呢
line_us 2014-12-20
  • 打赏
  • 举报
回复
只看看状况和分析
lm_whales 2014-12-20
  • 打赏
  • 举报
回复
#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; }
卖水果的net 2014-12-20
  • 打赏
  • 举报
回复
看 了半天回复,也不懂。。。
聚义舔刀 2014-12-19
  • 打赏
  • 举报
回复
我猜GetCurrentThread()的值有问题
draculamx 2014-12-19
  • 打赏
  • 举报
回复
来围观,只做过多线程的初级应用。。。。
mark_work 2014-12-19
  • 打赏
  • 举报
回复
围观的~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • 打赏
  • 举报
回复
你对当前线程SetThreadContext,那么可能会影响到当前线程的执行栈,下一条语句都不知道去哪了,因此可能出现各种奇异情况: if (SetThreadContext(当前线程)) {    在这里写代码很可能是没有任何意义的 } --- SetThreadContext一般都是用来搞其他线程的,搞自己的时候真不多
赵4老师 2014-12-19
  • 打赏
  • 举报
回复
引用 30 楼 sinservice 的回复:
[quote=引用 28 楼 zhao4zhong1 的回复:] 《30天自制操作系统》
在linus之前,全世界只有5个人独自设计并实现了操作系统,linus是第6个。 我根本不相信这种自制操作系统的说法。 我用8051汇编写个电子秤的程序,那的确是运行在纯粹硬件上的直接接触硬件的软件,但我不认为那就是操作系统。 [/quote] 你的成见阻挡了你学习提高的前路。 搜“空杯心态”
「已注销」 2014-12-19
  • 打赏
  • 举报
回复
引用 38 楼 luciferisnotsatan 的回复:
windows不有个协程么?CreateFiberEx 不能满足lz需求?
windows fiber限制很大,最多只能建立2000多个,太少了,不够用的。
luciferisnotsatan 2014-12-19
  • 打赏
  • 举报
回复
windows不有个协程么?CreateFiberEx 不能满足lz需求?
「已注销」 2014-12-19
  • 打赏
  • 举报
回复
引用 36 楼 fly_dragon_fly 的回复:
ret = setcontext(b); 在切换线程后,这个context是否把当前的esp也换掉了,导致ret的地址无效了,
有门了,但不对。 你看29L,那样写就可以。
fly_dragon_fly 2014-12-19
  • 打赏
  • 举报
回复
ret = setcontext(b); 在切换线程后,这个context是否把当前的esp也换掉了,导致ret的地址无效了,
FightForProgrammer 2014-12-19
  • 打赏
  • 举报
回复
getcontext setcontext 用这两个函数都是从主线程的栈中调用GetThreadContext、SetThreadContext。返回的时候作为协程会不会。。。不知道!~~~
加载更多回复(34)
内容概要:本文系统研究了虚拟同步发电机(VSG)的惯量-阻尼协同自适应并网控制策略及其稳定性分析,聚焦于提升高比例可再生能源接入背景下电网的频率稳定性。通过Simulink仿真平台与Matlab代码实现,构建了VSG并网系统的动态模型,深入探讨了惯量与阻尼参数的自适应调节机制,以优化系统对频率波动的响应能力。研究涵盖了双机并联VSG的功率精确分配、微电网黑启动过程、虚拟阻抗的引入以及预同步控制等关键技术,并结合根轨迹分析与调节系数对比,验证了所提控制策略在提升系统稳定性和动态性能方面的有效性。文章强调了协同自适应控制在现代电力系统中的关键作用,为微电网和分布式能源系统的稳定运行提供了理论支持和技术方案。; 适合人群:具备电力系统、自动控制或新能源并网等相关专业知识背景,熟悉Matlab/Simulink仿真工具,从事电力电子、微电网控制、可再生能源并网等领域科研或工程应用的研发人员及研究生。; 使用场景及目标:①掌握VSG在微电网及并网系统中的高精度建模与仿真方法;②深入理解惯量-阻尼协同自适应控制对电网频率稳定的优化机制;③应用于微电网黑启动、功率均分控制、虚拟阻抗设计及预同步等实际工程场景的算法开发与性能验证; 阅读建议:建议结合提供的Matlab代码与Simulink模型进行同步仿真操作,重点关注参数自适应调节模块的设计逻辑、根轨迹稳定性分析及不同调节系数下的动态响应对比,以深化对控制策略内在机理的理解与实际应用能力。

70,038

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧