rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

[kernel]将ipc中的上下文检查级别提高

Open jiladahe1997 opened this issue 3 years ago • 7 comments

拉取/合并请求描述:(PR description)

[ 使用信号量、互斥锁等ipc通信机制时,要求上下文“必须”是线程上下文,否则会导致 严重的异常(死锁、hardfault等)。

例如,线程A成功获取了互斥锁M,然后进入了中断,在中断中又尝试获取互斥锁M,此时会变成死锁。

上下文检查以宏定义的方式声明: RT_DEBUG_IN_THREAD_CONTEXT,此前一直位于 rtdebug.h 文件中,并根据 RT_DEBUG 宏定义来控制开关。

作为比较关键的检查,应该提高其重要级别,以防止有人关闭 RT_DEBUG 时,也自动关闭了 上下文检查。

参考: FreeRTOS/queue.c :1542行 https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/dca4f80a6be40f77848749ea18efd92b9d8ef66a/queue.c Linux Kernel /mutex.c: 280行 https://github.com/torvalds/linux/blob/master/kernel/locking/mutex.c

Signed-off-by: Mingrui Ren [email protected]




顺便一提,我遇到的问题是,在 rtthread_startup() 函数中(线程调度初始化完成之前),调用 rt_mutex_take()rt_mutex_release() 函数后,struct rt_mutex.value 的值会意外的变成2,导致后续可以有多个线程同时持有互斥锁。

总而言之,调用IPC通信机制的时候,上下文不能是: 中断 和 系统初始化 阶段。

]

以下的内容不应该在提交PR时的message修改,修改下述message,PR会被直接关闭。请在提交PR后,浏览器查看PR并对以下检查项逐项check,没问题后逐条在页面上打钩。 The following content must not be changed in the submitted PR message. Otherwise, the PR will be closed immediately. After submitted PR, please use a web browser to visit PR, and check items one by one, and ticked them if no problem.

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • [x] 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • [ ] 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • [x] 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • [x] 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • [x] 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • [x] 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • [x] 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • [ ] 本拉取/合并请求代码是高质量的 Code in this PR is of high quality
  • [ ] 本拉取/合并使用formatting等源码格式化工具确保格式符合RT-Thread代码规范 This PR complies with RT-Thread code specification

jiladahe1997 avatar Jan 28 '22 08:01 jiladahe1997

这个放在下个版本,对api所处环境的检查确实很重要

mysterywolf avatar Jan 28 '22 08:01 mysterywolf

这个放在下个版本,对api所处环境的检查确实很重要

@mysterywolf 好的,感谢回复。 到时候如需修改PR欢迎留言。

jiladahe1997 avatar Jan 28 '22 09:01 jiladahe1997

https://club.rt-thread.org/ask/article/3204.html

各类函数的用法,重点在于告诉用户怎么用,而不是让使用者毫无头绪的去乱试,每次遇到 assert 才恍然大悟,哦,这个函数不能这么用。这种想法是错的。

assert 是在开发阶段,或者说,是对入门者的一种快速暴力提示;对于一个熟练使用者来讲还依靠 assert 来定位用法错误,会对产品引入隐患的。 一个产品,绝对不能带着 assert 运行。虽然 ipc 中添加的这些 assert 经过实验阶段验证没有问题了,也不能让他们留在程序里。

@mysterywolf 就像前不久在微信群里提到的那样,检测宏最好放到函数开头,醒目的地方,做“警示”“提示”作用。让使用者方便,快速,第一件需要了解到的事儿就是知道这个函数的使用环境。

这个 pr ,除了增加了代码大小,并不能引导使用者使用上的更多注意。

thewon86 avatar Feb 09 '22 01:02 thewon86

顺便一提,我遇到的问题是,在 rtthread_startup() 函数中(线程调度初始化完成之前),调用 rt_mutex_take() 和 rt_mutex_release() 函数后,struct rt_mutex.value 的值会意外的变成2,导致后续可以有多个线程同时持有互斥锁。

rt_thread_startup 函数? 它里面需要用到锁了?

thewon86 avatar Feb 09 '22 01:02 thewon86

assert 是在开发阶段,或者说,是对入门者的一种快速暴力提示;对于一个熟练使用者来讲还依靠 assert 来定位用法错误,会对产品引入隐患的。 一个产品,绝对不能带着 assert 运行。虽然 ipc 中添加的这些 assert 经过实验阶段验证没有问题了,也不能让他们留在程序里。

感谢回复。 我赞同您的这个观点,assert 过于暴力,不应该在这里使用。或许可以参考 linux kernel,强制打印一段提示: Linux Kernel /mutex.c: 280行 https://github.com/torvalds/linux/blob/master/kernel/locking/mutex.c

各类函数的用法,重点在于告诉用户怎么用,而不是让使用者毫无头绪的去乱试,每次遇到 assert 才恍然大悟,哦,这个函数不能这么用。这种想法是错的。

而这个观点我认为有待商榷。 不应该说 README 里面写了,就把责任推给使用者。 受欢迎的产品常常是为用户着想,方便用户使用; 用户用着越方便,产品也就越受欢迎。

jiladahe1997 avatar Feb 09 '22 02:02 jiladahe1997

顺便一提,我遇到的问题是,在 rtthread_startup() 函数中(线程调度初始化完成之前),调用 rt_mutex_take() 和 rt_mutex_release() 函数后,struct rt_mutex.value 的值会意外的变成2,导致后续可以有多个线程同时持有互斥锁。

rt_thread_startup 函数? 它里面需要用到锁了?

没有。 是我自己在 rt_thread_startup 增加了初始化步骤,在初始化步骤中误调用了锁。 但是由于没有任何错误相关提示,导致排查花了比较久的时间。

jiladahe1997 avatar Feb 09 '22 02:02 jiladahe1997

assert 是在开发阶段,或者说,是对入门者的一种快速暴力提示;对于一个熟练使用者来讲还依靠 assert 来定位用法错误,会对产品引入隐患的。

@thewon86 我同意,我之前也在想直接assert干掉是不是太危险了,这个assert在投入产品之后,即便出问题也不能直接卡死,否则,真正的bug可能没引发什么问题,反倒是assert直接把产品给卡死了。

@jg1uaa 先不用着急改这个pr,现存的一些安全类型的宏函数也有一些问题,等把现存的优化好,成熟的经验就可以放在这个pr上了。

mysterywolf avatar Feb 09 '22 02:02 mysterywolf