嵌入式驱动学习第六周——内核函数调用(堆栈打印)

前言

   在内核中,函数调用堆栈非常重要,因为它可以帮助开发人员理解代码是如何执行的,从而进行调试、性能优化或问题排查。堆栈可以显示当前执行的函数以及导致该函数调用的先前函数,从而形成一个函数调用链。本篇博客就介绍堆栈打印内核函数的调用。

   嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程,未来预计四个月将高强度更新本专栏,喜欢的可以关注本博主并订阅本专栏,一起讨论一起学习。现在关注就是老粉啦!

目录

  • 前言
  • dump_stack函数
  • WARN_ON函数
  • BUG_ON函数
  • panic函数
  • 参考资料

dump_stack函数

   该函数作用是打印内核调用堆栈,并打印函数的调用关系。

   下面给出一段实验代码,在该内核模块中,我们定义四个函数aaabbbcccddd,然后bbb中调用aaaccc中调用bbbddd函数谁都不调用。在入口函数中,我们调用cccddd函数。

   在aaa函数中使用dump_stack函数,查看aaa函数的调用栈

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>void aaa(void) {printk(KERN_EMERG "aaa\n");dump_stack();msleep(100);
}void bbb(void) {printk(KERN_EMERG "bbb\n");aaa();msleep(100);
}void ccc(void) {printk(KERN_EMERG "ccc\n");bbb();msleep(100);
}void ddd(void) {printk(KERN_EMERG "ddd\n");msleep(100);
}static int __init chrdevTest_init(void) {printk(KERN_EMERG "INIT func\r\n");ccc();ddd();return 0;
}static void __exit chrdevTest_exit(void) {printk(KERN_EMERG "EXIT func\r\n");
}module_init(chrdevTest_init);
module_exit(chrdevTest_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wp");

   加载驱动后,显示信息如下所示,可以看到先打印INIT func,然后按照调用关系分别打印ccc,bbb,aaa。

   之后就是aaa的调用栈,框中就是调用关系,因为是chrdevTest_init调用cccccc调用bbbbbb调用aaa,由于Cortex-A处理器的堆栈是向下生长的,因此先压入chrdevTest_init函数(地址较大),在压入ccc函数(地址递减),以此类推到aaa函数。

   最后打印了一下谁都不调用的ddd函数。
在这里插入图片描述

   dump_stack()函数有助于我们调试,查看目标函数的调用关系

   如果信息消失了,可以使用dmesg指令重新再控制台打印出来

WARN_ON函数

   WARN_ON(condition)函数的作用是,在括号中的条件成立时,内核会抛出栈回溯,打印函数的调用关系,通常用于内核抛出一个警告,暗示某种不太合理的事情发生了。

   WARN_ON实际上也是调用了dump_stack,只是多了一个条件判断是否成立。

   在刚刚dump_stack函数的实验代码基础上,我们将aaa函数中dump_stack函数调用的位置改为WARN_ON(1)

void aaa(void) {printk(KERN_EMERG "aaa\n");WARN_ON(1);						// 条件为真,打印调用信息msleep(100);
}

   加载模块后,基本和上一个dump_stack的结果一样,但是可以看到,dump_stack函数也被压进调用栈了,因此可以确定WARN_ON是调用的dump_stack函数。
在这里插入图片描述

   现在我们将WARN_ON中的条件改为false,再看看结果:

void aaa(void) {printk(KERN_EMERG "aaa\n");WARN_ON(0);						// 条件为假,不打印调用信息msleep(100);
}

   可以看到控制台并没有输出调用栈。

在这里插入图片描述

BUG_ON函数

   内核中也有许多地方用到了BUG_ON函数,这个函数就像一个内核运行时的断言,意味着本来不该执行到BUG_ON这句,一旦执行就会抛出oops,导致栈的回溯和错误信息的打印,大部分体系结构把BUG()BUG_ON()定义成某种非法操作,这样自然会产生需要的oops

   在上面代码的基础上,将aaa函数中改为BUG_ON函数

void aaa(void) {printk(KERN_EMERG "aaa\n");BUG_ON(1);msleep(100);
}

   加载模块后,打印出来的信息如下所示,可以看到其中抛出了oops,并且最后并没有打印ddd函数的信息。然后函数调用关系也打印出来了,寄存器值也都打印出来了。

在这里插入图片描述

   我们将BUG_ON中的条件改为false

void aaa(void) {printk(KERN_EMERG "aaa\n");BUG_ON(0);msleep(100);
}

   加载驱动后如下所示,可以看到不打印任何堆栈信息,并且ddd函数可以顺利执行。

在这里插入图片描述

panic函数

   可以用panic()引发更严重的错误。调用panic()不但会打印错误消息(Oops)而且还会挂起整个系统。显然,你只应该在极端恶劣的情况下使用它。

   将同样的位置换为panic()函数

void aaa(void) {printk(KERN_EMERG "aaa\n");panic("###########################################wpwpwpwp");msleep(100);
}

   可以看到,打印完aaa函数后,控制台打印出panic中的字符串,然后整个进程进入到了阻塞状态。

在这里插入图片描述

参考资料

[1] Linux打印内核函数调用栈(dump_stack)

[2] Linux内核之BUG_ON()和WARN_ON()

[3] linux 内核态调试函数BUG_ON()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/795749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件无线电原理

常规软件无线电接收器&#xff1a; 首先&#xff0c;来自天线的射频信号被放大&#xff0c;通常射频部分利用一个调谐器将感兴趣的频段区域的信号进行放大。这个放大的射频信号被送入一个混频器。来自本振的信号也被送入混频器&#xff0c;其频率由无线电的调谐控制决定。混频器…

【LeetCode】--- 动态规划 集训(二)

目录 一、63. 不同路径 II1.1 题目解析1.2 状态转移方程1.3 解题代码 二、931. 下降路径最小和2.1 题目解析2.2 状态转移方程2.3 解题代码三、174. 地下城游戏3.1 题目解析3.2 状态转移方程3.3 解题代码 一、63. 不同路径 II 题目地址&#xff1a; 不同路径 II 一个机器人位于…

传输层 --- TCP (下篇)

目录 1. 超时重传 1.1. 数据段丢包 1.2. 接收方发送的ACK丢包 1.3. 超时重传的超时时间如何设置 2. 流量控制 3. 滑动窗口 3.1. 初步理解滑动窗口 3.2. 滑动窗口的完善理解 3.3. 关于快重传的补充 3.4. 快重传和超时重传的区别 4. 拥塞控制 4.1. 拥塞控制的宏观认识…

「 典型安全漏洞系列 」11.身份验证漏洞详解

身份验证是验证用户或客户端身份的过程。网站可能会暴露给任何连接到互联网的人。这使得健壮的身份验证机制成为有效的网络安全不可或缺的一部分。 1. 什么是身份验证 身份验证即认证&#xff0c;是验证给定用户或客户端身份的过程。身份验证漏洞使攻击者能够访问敏感数据和功…

Linux网络基础 (三) —— Socket

文章目录 Socket 编程基本概念Socket背景Socket 为了解决什么问题 socketsockaddr结构sockaddrsockaddr_insockaddr 和 sockaddr_in 的关系sockaddr_un 示例代码 &#x1f396; 博主的CSDN主页&#xff1a;Ryan.Alaskan Malamute &#x1f4dc; 博主的代码仓库主页 [ Gitee ]&…

【MySQL】数据操作语句(DML)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习计网、mysql和算法 ✈️专栏&#xff1a;MySQL学习 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…

【论文通读】AgentStudio: A Toolkit for Building General Virtual Agents

AgentStudio: A Toolkit for Building General Virtual Agents 前言AbstractMotivationFramework评估GUI GroudingReal-World Cross-Application Benchmark Suite Conclusion 前言 来自昆仑万象的一篇智能体环境数据大一统框架工作&#xff0c;对未来计算机智能体的发展具有指…

FPGA常用IP核之FIFO学习

IP核是FPGA芯片公司提供的逻辑功能块&#xff0c;在FPGA芯片中可以进行优化和预先配置&#xff0c;可以直接在用户设计的程序中使用&#xff0c;应用范围很广。在FPGA设计开发过程中使用IP核&#xff0c;可以大大的缩短开发周期&#xff0c;高度优化的IP核可以使FPG开发工程师专…

前端三剑客 —— CSS (第六节)

目录 内容回顾&#xff1a; 弹性布局属性介绍 案例演示 商品案例 布局分析 登录案例 网格布局 内容回顾&#xff1a; 变量&#xff1a;定义变量使用 --名称&#xff1a;值&#xff1b; 使用变量&#xff1a; 属性名&#xff1a;var&#xff08;--名称&#xff09;&a…

虚拟主机、VPS主机和云服务器的区别

对于每个建站新手来说&#xff0c;首先要解决的就是服务器购买的问题&#xff0c;目前市面有很多类型的服务器&#xff0c;常见的有&#xff1a;阿里云、腾讯云、Vultr云服务器&#xff0c;也有RackNerd、Cloudways等提供的VPS&#xff0c;还有SiteGround、ChemiCloud 、 Hosti…

数据结构之堆底层实现的循序渐进

题外话 把没写的都补回来! 正题 堆 概念 堆是一棵完全二叉树&#xff0c;因此可以层序的规则采用顺序的方式来高效存储&#xff0c; 大根堆:指根结点比左右孩子都大的堆 小根堆:指根结点比左右孩子都小的堆 性质 1.堆中某个节点的值总是不大于或不小于其父节点的值 2…

鸿蒙OS元服务开发:【(Stage模型)设置应用主窗口】

一、设置应用主窗口说明 在Stage模型下&#xff0c;应用主窗口由UIAbility创建并维护生命周期。在UIAbility的onWindowStageCreate回调中&#xff0c;通过WindowStage获取应用主窗口&#xff0c;即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性&…

每日一题(leetcode1026):节点与其祖先的最大差值--dfs

考虑到只能计算祖先之间的节点差而不能计算兄弟之间的节点差&#xff0c;所以思考使用dfs来解决该题。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), ri…

嵌入式开发学习---(部分)数据结构(无代码)

数据结构 为什么学习数据结构&#xff1f; 1&#xff09;c语言告诉如何写程序&#xff0c;数据结构是如何简洁高效的写程序 2&#xff09;遇到一个实际问题&#xff0c;需要写程序去实现相应功能&#xff0c;需要解决那两个方面的问题&#xff1f; 如何表达数据之间的逻辑规律…

背包问题---

一、背包模型 有一个体积为V的背包,商店有n个物品,每个物品有一个价值v和体积w,每个物品只能被拿一次,问能够装下物品的最大价值。 这里每一种物品只有两种状态即"拿"或"不拿". 设状态dp[i][j]表示到第i个物品为止,拿的物品总体积为j的情况下的最大价…

一、持续集成介绍

持续集成介绍 一、什么是持续集成二、持续集成的流程三、持续集成的组成要素四、持续集成的好处 一、什么是持续集成 持续集成&#xff08;CI&#xff09;指的是&#xff0c;频繁地&#xff08;一天多次&#xff09;将代码集成到主干。持续集成的目的&#xff0c;就是让产品可…

LeetCode:1483. 树节点的第 K 个祖先(倍增 Java)

目录 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 实现代码与解析&#xff1a; 倍增 原理思路&#xff1a; 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#…

软件测试——黑盒测试

黑盒测试也就是针对功能进行测试&#xff0c;白盒测试就是后端根据自己的代码逻辑进行一下自测&#xff0c;灰盒测试就是黑盒和白盒的混合测试。 1.黑盒测试主要发现以下类型的错误 对比需求规格说明书功能遗漏或者不一致。 接口错误 数据库连接访问错误 效率不高&#xff…

【好书推荐-第十四期】《 互联网大厂晋升指南:从P5到P9的升级攻略》

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号&#xff1a;洲与AI。 &#x1f388; 本文专栏&#xff1a;本文收录…

第八讲 Sort Aggregate 算法

我们现在将讨论如何使用迄今为止讨论过的 DBMS 组件来执行查询。 1 查询计划【Query Plan】 我们首先来看当一个查询【Query】被解析【Parsed】后会发生什么&#xff1f; 当 SQL 查询被提供给数据库执行引擎&#xff0c;它将通过语法解析器进行检查&#xff0c;然后它会被转换…