搞了台电脑,昨天把系统装了下,继续搞事:
上次基于内核代码openat的系统打印被操作的文件名,发现不成功,很奇怪,这种问题内核不可能会犯这种低级别的问题吧?
反过来想,那不是内核的问题,肯定就是我们这边写打印代码的问题了,并且系统也提示到出错的调用栈,那只能回归代码分析,一共没几行代码,这有点尴尬。。。。
那先打开SourceInsight(有兴趣可以安装下,阅读代码还可以,不过写代码有点不太好):
cd /root/.wine/drive_c/Program\ Files/Source\ Insight\ 3;
wine Insight3.exe &
开始打印filename这个参数的时候,一看这:
感觉肯定是字符串,一打印就出调用栈。。。这。。。
估计这里这有套路。。那我们假设,不知道这个filename是个什么东西,那顺着代码往下找:
从上边来看,这个好像是const char __user *这种类型,感觉也不知道是啥东西,那先不管,继续往下看:
往这里一看,就比较容易了解了,这里一看就是内核在解析这个从操作系统上层传来的参数,从这里来看,关键就是找到struct filename 这个结构体,那我们再找找,Source Insight在这里好像有点bug,好像找不到,那只能去Terminal搜索,用的下面这个命令行,其实这个命令行可以优化些,先不管:
root@A:/usr/src/linux-6.9.0/include# find -name "*.h" | xargs -i grep -Hrn "struct filename {" {}
这种查找,有时候一次不一定能成功,多尝试几次就好了。好,那现在我们找到了,看看这个结构体详细的定义:
按照理解,直接把name字段打印出来就行了,那简单啊,注意啊,要在1402到1404之后打印,不然功败垂成了:
其实我在添加完这行代码后,编译内核的时候心里也有点慌,这不会也不对吧?哈哈,这个时候来看,这行代码难度不大吧。
然后编译内核,重启代码,然后查看日志的显示:
从这里来看,跟我们修改的文件,函数,行号,打印的日志都能对应得上,那说明我们的修改是正确的。
但是这里有一个问题,我们自己未从操作系统应用层面创建文件和写入文件,那表示我们的打印接口不一定对啊,怎么办呢?
很简单,手动创建一个文件,随便写入点内容,这样再去内核日志里看,就可以知道是否成功了:
这里使用的touch命令和echo命令:
然后再搜索日志文件syslog文件,可以看到与我们创建的文件名是一样的,这样表示我们的猜想和操作是正确的。
在实际的操作中,需要有些耐心,并且验证的周期比较长。
代码合入hash值:
合入代码与系统运行详细日志https://gitee.com/r77683962/linux-6.9.0/commit/64452ad920a29e5f096dfb6dd112643621158f03
基于这样的思路,实际上,我们是可以看到操作系统从应用层面的操作到内核层面的处理的接口,可以通过自己阅读代码,添加日志,看到内核代码的执行流程。