0
点赞
收藏
分享

微信扫一扫

软件调试翻车现场:误把八进制当成十六进制


前言

  • 最近在调试软件时,碰到了一个比较【迷惑】的标志位问题,一个32位的mask,软件调试,发现获取的值不对
  • 问题发出去【求助】的瞬间,我顺便看了一下这个文件的所在目录,对比了下 Linux目录下的文件,【豁然开朗】了
  • ​fcntl.h​​,我问了一个问题,随后发现这个问题说明我【基础知识】不好,这里其实是【八进制】数值表示方法,只是编程中接触的少而已。
  • 注意:这里是【八进制】,C语言基础啊,我一时竟没有看出来,记录下来,以此勉励。

问题描述

  • 环境:RT-Thread 4.1.0
  • vconsole 软件包:用于终端切换
  • 问题:console shell 终端切换后,发现无法正常的输入
  • RT-Thread Studio gcc 环境验证:问题必现
  • Keil MDK5 arm_clang 环境验证:问题必现
  • 替换RT-Thread 内核,发现是一个【RT_USING_POSIX_STDIO】导致的,不开启这个宏,是正常的,开启这个【RT_USING_POSIX_STDIO】,发现了异常
  • 经过软件排查,发现切换后,有个软件逻辑一直无法跑通

调试流程

  • 软件调试:在这个函数打上断点后,控制台随便按个键盘按键,发现能触发【接收回调】,问题就是:这个【等待队列】是空的,没有唤醒【shell 进程】

static rt_err_t fops_rx_ind(rt_device_t dev, rt_size_t size)
{
rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
return RT_EOK;
}

  • 开机不切换串口,这个唤醒后,也进入这个【接收回调】函数,并且整个【等待队列】不为空,唤醒等待队列,就触发【shell 线程】正常读取,shell 功能正常

切换逻辑

  • 切换时,需要设置一个【标志位】,有了这个标志位,【shell 终端对象】读数据时,就不再:【无限等待】,而这个标志位没有置位
  • 软件调试发现一个【奇怪的问题】:标志位跟自己想的不一样

软件调试翻车现场:误把八进制当成十六进制_十六进制

软件调试翻车现场:误把八进制当成十六进制_十六进制_02

static int _fops_ioctl(struct dfs_fd *fd, int cmd, void *args)
{
rt_device_t device;
int flags = (int)(rt_base_t)args;
int mask = O_NONBLOCK | O_APPEND;

device = (rt_device_t)fd->data;
switch (cmd)
{
case FIONREAD:
break;
case FIONWRITE:
break;
case F_SETFL:
flags &= mask;
fd->flags &= ~mask;
fd->flags |= flags;
break;
}

return rt_device_control(device, cmd, args);
}

#define O_NONBLOCK    04000
#define O_APPEND 02000

  • 这个:​​ int mask = O_NONBLOCK | O_APPEND;​​ 获取的,不是:0x6000,而是:0xC00。
  • 这个 04000 ,有个 0 前导,就是 【八进制】
  • 也就是这里的 O_NONBLOCK 04000,没有​​0x​​​前导,是个【八进制】数,十六进制为:​​0x800​
  • ​O_APPEND 02000​​​ 转换为十六进制: ​​0x400​
  • ​0x800 | 0x400 确实为: 0xc00​

基础知识

  • 【八进制】用的比较少,可能思维里按【十六进制】处理,会造成困扰
  • 这个基础知识,还是要多看,软件编程会涉及多方面的知识,要多积累

问题解决

  • 其实就是上面:vconsole.c 中的:​​_fops_ioctl​​​ 没有处理:​​F_SETFL​​​ ,导致​​fd->flags​​没有正确的设置上,从而接收回调【唤醒后】,让【shell 线程】去读取【输入的字符】,导致又进入了【wait forever】,从而【shell 线程】死等在【老的终端】,新切换的终端,等待队列为空,导致【shell 线程】一直挂起。

小结

  • 注意【八进制】的表示方法:数字​​0​​​作为前导,而不是字母​​O​​。八进制的表示方法用的不多,但不能误当成【十进制】,也不能误当成【十六进制】
  • Linux系统中采用三位八进制的数字来表示文件的操作权限,方便和用户组对应容易看。这个知识点后面深入看一下。
  • ​O_NONBLOCK​​​ ​​O_APPEND​​ 这种,一般用于:文件的操作,是文件的属性


举报

相关推荐

0 条评论