Linux内核调试篇——获取内核函数地址的四种方法(一文解决)

在内核调试中,经常需要知道某个函数的地址,或者根据函数地址找到对应的函数,从而进行更深一步的debug。

下面介绍四种获取内核函数地址的方法:

1、System.map

在编译Linux内核时,会产生一个内核映像文件System.map,也叫内核符号表

内核符号表是一个映射,它将内核代码段中的地址映射到对应的函数名或全局变量名。

System.map文件中,每一行都包含一个内核符号,每个符号包含三部分:

  • 地址:符号在内核内存中的地址。
  • 类型:符号的类型。例如,"T"表示该符号是一个在代码段中的函数。
  • 名称:符号的名字,可以是函数名或者变量名。

例如,我们要查找名为“do_fork”的函数的地址,可以使用以下命令:

grep ' do_fork' System.map

然后会得到类似于这样的输出:

c0105020 T do_fork

这代表,c0105020就是函数do_fork的地址,T代表该符号是个函数。

或者,直接打开System.map搜索对应函数名或者地址。System.map内容类似如下:

c0004000 A swapper_pg_dir
c0008000 T __init_begin
c0008000 T _sinittext
c0008000 T _stext
c0008000 T stext
c0008034 t __enable_mmu
c0008060 t __turn_mmu_on
......

A、T、t等都代表不同的类型,具体类型的定义可参考:

2、vmlinux

vmlinux也是Linux编译出来的内核映像文件,可以通过nmobjdumpreadelf等工具来查看它的符号表,从而获取函数地址。

2.1 nm读取vmlinux

nm命令是用于查看二进制文件(如可执行文件、目标文件、库)的符号表的工具,所以可以用nm命令来读取vmlinux里的符号表。

  • nm查找vmlinux中函数名为do_fork的地址:
nm vmlinux | grep "do_fork"
  • nm查找vmlinux中地址为c0105020的符号:
nm vmlinux | grep c0105020

nm命令的输出,与System.map类似,会的得到类似于以下的输出:

c0105020 T do_fork

2.2 objdump反汇编vmlinux

objdump工具用于反汇编,可以将vmlinux反汇编出来,得到的反汇编文件就会包含函数名和对应的地址,可以直接查看文本内容。

  • 使用objdump查看vmlinux函数地址
objdump -d vmlinux | grep "函数名"

这会返回与指定函数名匹配的符号的地址、类型和名称。objdump-d选项表示反汇编代码。

也可以将vmlinux的内容全部反汇编出来,重定向到一个文件,然后直接查看文本内容:

objdump -D vmlinux > vmlinux_dump.txt

上述命令会将vmlinux所有内容反汇编,并将结果输出到vmlinux_dump.txt文件中,-D表示反汇编所有代码段。

2.3 readelf读取vmlinux

使用readelf也可以读取vmlinux的符号表,命令如下:

readelf -s vmlinux

由于vmlinux比较大,如果要查找某个函数的地址,需要使用grep进行过滤。

例如,找到do_fork函数的地址,你可以使用以下命令:

readelf -s vmlinux | grep "do_fork"

然后,你就会看到类似这样的输出:

56481: c10601e0    96 FUNC    GLOBAL DEFAULT    1 do_fork

输出内容表示,do_fork函数的地址是c10601e0

3、/proc/kallsyms

vmlinux是编译时生成的,假设你没有vmlinux这个文件,只有正在运行的Linux系统,此时也可以通过/proc/kallsyms获取函数地址。

/proc/kallsyms是一个由运行中的内核动态生成的虚拟文件,它反映了当前运行的内核的状态

通常这个节点是不会打开的,因为会增加内核大小,要使用这个节点,需要打开内核选项:

CONFIG_KALLSYMS=y

如果想获取do_fork函数的地址,可以使用以下命令:

cat /proc/kallsyms | grep " do_fork"

然后会返回一个包含do_fork函数地址的行,如:

ffffffff810b57b0 T do_fork

输出内容表示do_fork函数的地址是ffffffff810b57b0

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linuxc/c++高级开发【直播公开课】

零声白金VIP体验卡:零声白金VIP体验卡(含基础架构/高性能存储/golang/QT/音视频/Linux内核)

4、内核接口

也可以在代码中获取内核符号表,同样需要打开内核选项CONFIG_KALLSYMS=y

kallsyms_lookup_name

  • 已知函数名,获取地址:
kallsyms_lookup_name("函数名" )

该函数会返回对应函数名的地址。

sprint_symbol

  • 已知地址,返回对应符号:
#include <linux/kallsyms.h>int sprint_symbol(char *buffer, unsigned long address)
  • buffer:符号名缓存区,保存结果。
  • address:符号地址。

原文作者:嵌入式Linux充电站

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

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

相关文章

低代码平台全解析:衍生历程、优势呈现与未来趋势一览无余

在数字化时代&#xff0c;应用程序的开发与更新已成为企业保持竞争力的关键。传统的编码方式&#xff0c;虽然精细且功能强大&#xff0c;但耗时且要求开发者具备较高的技术水平。在这样的背景下&#xff0c;低代码开发平台的出现无疑为企业带来了福音。 低代码开发平台是一种创…

开关电源测试方法分享:开关电源关机维持时间的测试步骤、测试标准

开关电源关机维持时间是指切断电源后输出电压下降到稳压范围外为止的时间。关机维持时间是开关电源测试项目之一&#xff0c;测试时需要用到交流电源、电子负载、示波器等测试设备。那么开关电源测试系统要如何测试关机维持时间呢? 开关电源关机维持时间的测试步骤 关机维持时…

Leetcode—53.最大子数组和【中等】

2023每日刷题&#xff08;三十四&#xff09; Leetcode—53.最大子数组和 前缀和算法思想 参考灵茶山艾府 实现代码 #define MAX(a, b) ((a > b) ? (a) : (b)) #define MIN(a, b) ((a < b) ? (a) : (b)) int maxSubArray(int* nums, int numsSize) {int ans INT_…

Springboot+vue的机动车号牌管理系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频: Springbootvue的机动车号牌管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的机动车号牌管理系统&#xff0c;采用M&#xff08;model&#xff09…

Web自动化测试工具的关键功能

当涉及到 Web 应用程序开发和维护&#xff0c;自动化测试工具发挥着至关重要的作用。这些工具不仅仅简化了测试过程&#xff0c;还有助于保障软件质量、提高生产力和减少人力资源的投入。以下是Web自动化测试工具提供的关键功能&#xff1a; 1. 自动化脚本录制和回放功能 Web 自…

餐饮品牌的市场不断下沉释放信号,乡镇外卖的发展机会来临

随着越来越多的人开始使用互联网&#xff0c;"小镇经济"迅速兴起&#xff0c;成为消费市场的热点&#xff0c;这是因为小镇人口庞大&#xff0c;消费需求快速增长。 数据表明&#xff0c;在中国消费市场中&#xff0c;下沉市场的消费规模占比高达17万亿元&#xff0…

床旁婴儿床上架亚马逊美国站 ASTM F2906测试的重要性

在当今的育儿环境中&#xff0c;婴儿床已经成为了一种必需品。然而&#xff0c;对于许多父母来说&#xff0c;选择一个既安全又符合标准的婴儿床是一项重要的任务。其中&#xff0c;ASTM F2906测试是评估婴儿床安全性能的重要标准。 床旁婴儿床 如果您在亚马逊商城发布商品&am…

澳洲猫罐头真实水平如何?我家亲自喂养过的优质猫罐头推荐给大家

当我们选择猫罐头时&#xff0c;要关注它的营养配方是否完整均衡、原料是否新鲜优质以及生产工艺是否科学可靠。只有满足这三个条件的猫罐头&#xff0c;才能称得上是高品质的。 猫罐头要营养均衡&#xff0c;好的配方不能少&#xff1b;猫罐头成品要优质&#xff0c;原材料要…

redis 非关系型数据库

redis 非关系型数据库&#xff0c;缓存型数据库。 关系型数据库和非关系型数据库的区别 关系型数据库是一个机构化的数据库&#xff0c;行和列。 列&#xff1a;声明对象 行&#xff1a;记录对象属性。 表与表之间是有关联&#xff0c;使用sql语句&#xff0c;来对指定的表…

C++ 继承和派生 万字长文超详解

本文章内容来源于C课堂上的听课笔记 继承和派生基础 继承是一种概念&#xff0c;它允许一个新创建的类&#xff08;称为子类或派生类&#xff09;获取另一个已经存在的类&#xff08;称为父类或基类&#xff09;的属性和行为。这就好比是子类继承了父类的特征。想象一下&…

【LeetCode刷题-字符串】--6.N字形变换

6.N字形变换 方法&#xff1a;使用二维矩阵模拟 根据题意&#xff0c;当在矩阵中填写字符时&#xff0c;会向下填写r个字符&#xff0c;然后向右继续填写r - 2个字符&#xff0c;最后回到第一行&#xff0c;因此Z字形变换的周期是t r r - 2 2r - 2&#xff0c;是|/,每个周期…

选择java商城开发商需要注意哪些方面?

Java商城开发是一项庞大而复杂的任务&#xff0c;选择一家合适的开发商至关重要。那么&#xff0c;我们在选择Java商城开发商时&#xff0c;需要注意哪些方面呢&#xff1f; 1、专业经验 选择具有丰富经验的开发商是至关重要的。开发商应该拥有多年的Java开发经验&#xff0c;…