使用Qemu+gdb来调试内核

2023-11-19

原文地址:http://blog.csdn.net/iamljj/article/details/5655169

昨天听别人讲使用Qemu和gdb来实现源码级内核调试,今天试了一下,果然非常方便,现简单的记录一下。

 Qemu是一个开源的虚拟机软件,能够提供全系统的仿真,可以运行在多个平台上,并仿真多个别的平台。Qemu虚拟机是采用动态翻译来实现CPU的仿真的,对硬件的依赖程度低,通过它提供的众多参数,你能够对虚拟的机器进行定制以满足你的需求。

 要想对内核进行调试,那自然需要重新编译内核了,编译内核的具体方法这里就不罗嗦了,需要注意的是在配置内核时,要将“kernel hacking"中的“compile the kernel with debug info"选上,否则没有调试信息,gdb也难为无米之炊。

 编译好内核之后,我们还需要制作一个rootfs作为Qemu虚拟机的硬盘,这个步骤可以通过Qemu来完成,大致的步骤如下:

1. 创建一个虚拟的硬盘

# qemu-img create foobar.img 8G  # 创建一个8G的虚拟硬盘

2. 在虚拟的硬盘上安装一个Linux系统

# qemu -hda foobar.img -cdrom xxx.iso -boot d -m 512 -enable-audio -localtime 

# xxx.iso为某linux的发行版本的iso,该命令就是要从iso启动,并将系统安装到foobar.img中

当然,其实也可以将init ram disk作为Qemu的rootfs,但这时需要对initrd进行修改,如果你对initrd不熟悉的话,最好还是花点时间,做个rootfs,这个可以省去一些麻烦。

 

Qemu虚拟机只是提供了一个虚拟的机器,使得程序运行在虚拟机中如同运行真实的物理机器上一样,除此以外,Qemu还必须能够对虚拟机进行完全的控制,但Qemu和gdb又是怎么扯上关系的呢?这是因为Qemu中内置了gdbserver,这使得Qemu能够和远程的gdb进行通讯,通过远程的gdb来控制Qemu虚拟机的执行,从而达到调试的目的。具体的操作如下:

1. 切换到刚刚编译的内核的路径,然后启动Qemu

# qemu -kernel arch/x86/boot/bzImage -initrd /boot/initrd.img-2.6.31-22-generic -gdb tcp::1234 -S

# -kernel 用来指定内核,注arch/x86/bzImage是不带调试信息的内核,vmlinux是带有调试信息的内核

# -initrd 用来指定内核启动时使用的ram disk,

# -gdb tcp::1234表示启动gdbserver,并在tcp的1234端口监听,-S表示在开始的时候冻结CPU直到远程的gdb输入相应的控制命令

2. 启动gdb,并和Qemu进行联系,然后你就可以像调试应用程序那些调试内核了

# gdb

(gdb) file vmlinux

(gdb) target remote :1234

(gdb) b start_kernel

(gdb) c

呵呵,是不是很简单,下面再简单的介绍一下gdb常用的一些调试命令:
help:即时帮助,当你不太记得或不太熟悉某些命令时,一个help就可以搞定
edit:在gdb中使用$EDITOR对某个文件进行编辑,在开始之前可以将$EDITOR设置为自己喜欢的编辑器
list:列出被调试程序当前上下文的源程序
make:相当于在shell中运行make,对工程进行编译,编译完成后使用run即可重新开始调试
run:简写为r,开始运行被调试的程序
break:简写为b,设置一个断点,该断点可以为某个文件的某行,也可是某个函数名,还可以是某个地址,
此外通过if参数还可以设置条件断点

 

backtrace:输出调用堆栈
info:查看当前gdb的各种信息,如断点信息,调用堆栈等

 step:简写为s,单步执行,每次执行一行源程序,会跟踪进入函数

 next:简写为n,单步执行,每次执行一行源程序,不跟踪进入函数

stepi:简写为si,单步执行,每次执行一个指令,会跟踪进入函数
stepi N:简写为si N,多步执行,每次执行N步指令,会跟踪进入函数
 nexti:简写为ni,单步执行,每次执行一个指令,不跟踪进入函数

finish:执行直到从当前函数返回

until:简写为u,执行直到所在的循环结束
continue:简写为c,继续执行直到下一个断点或程序结束或gdb收到信号
print:简写p,用来输出某个变量的值,只输出一次,输出结构时可以设置“set print pretty on“,这样观察更方便 
display:观察某个变量,每次执行时都显示相应的变量

x:查看内存,通过相应的参数来执行内存的地址和要显示多少数据

x/i: 显示内存下一条指令
x/Ni ADDR: 从
内存地址ADDR处开始显示N步指令

b uploadmgr.c:upload 表示在uploadmgr.c文件的upload函数打上断点。

b uploadmgr.c:12  表示在uploadmgr.c文件的12行打上断点.

nfo break可以查看当前的断点信息

delete  1 表示删除第一个断点  (用info break查看的 断点号)

delete 不带参数是删除所有断点

gdb xxx |tee newfile  可以将gdb过程中,保存所有输出到newfile中去
 set args a b c  ,设置调试程序的参数
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Qemu+gdb来调试内核 的相关文章

  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 如何确保 numpy BLAS 库可用作动态加载库?

    The theano安装文档 http www deeplearning net software theano install html troubleshooting make sure you have a blas library指
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • CentOS目录结构是树形的吗?

    CentOS 上有相当于树的东西吗 如果你的 Centos 系统上没有安装 tree 无论如何我通常建议服务器设置使用最小安装磁盘 你应该在命令行中输入以下内容 yum install tree y 如果没有安装 那是因为您没有正确的存储库
  • “grep -q”的意义是什么

    我正在阅读 grep 手册页 并遇到了 q 选项 它告诉 grep 不向标准输出写入任何内容 如果发现任何匹配 即使检测到错误 也立即以零状态退出 我不明白为什么这可能是理想或有用的行为 在一个程序中 其原因似乎是从标准输入读取 处理 写入
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • 如何从 Linux 命令行获取视频文件的分辨率(宽度和高度)?

    我一直在挖掘 mplayer mencoder 和 ffmpeg 文档 但我似乎无法想出anything 我对输出格式不是特别挑剔 因为我可以使用正则表达式将其拉出来 我只是似乎无法首先获取数据 Use ffprobe https ffmp
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • 如何获取 linux 实用程序 tail 的源代码?

    这个命令确实非常有用 但是我可以在哪里获取源代码以查看内部发生的情况 thanks tail 实用程序是 Linux 上 coreutils 的一部分 源压缩包 ftp ftp gnu org gnu coreutils coreutils
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • Linux 中热插拔设备时检测设备是否存在

    我正在运行 SPIcode http lxr free electrons com source drivers spi spi omap2 mcspi c在熊猫板上 我想知道其中的哪个功能code http lxr free electr
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif

随机推荐

  • 掩码、ip段转为单个ip地址,解决ValueError: IP(‘x.x.x.x/x‘) has invalid prefix length ()

    最近碰到的问题 简单记录下 from IPy import IP import re os time 解析10 245 1 1 10 245 1 10这种类型的ip段 def all for one dates ipx dates spli
  • R语言应用序列模式挖掘揭示客户购买行为:深度学习与机器学习的视角

    目录 序列模式挖掘 一个简介 使用R进行序列模式挖掘 应用深度学习和机器学习改善购买行为预测
  • 无向图的深度优先遍历非递归_数据结构系列图

    图 01 图的基本定义与基本术语 基本概念 图 Graph 是由顶点的集合和顶点之间边的集合组成 通常表示为 G V E 其中 G表示一个图 V是图G中顶点的集合 E是图G中边的集合 在图中的数据元素 我们称之为顶点 Vertex 顶点集合
  • 6.OS运行机制(补充)

    中断
  • C#的new关键字的几种用法

    一共有三种用法 在 C 中 new 关键字可用作运算符 修饰符或约束 1 new 运算符 用于创建对象和调用构造函数 这种大家都比较熟悉 没什么好说的了 2 new 修饰符 在用作修饰符时 new 关键字可以显式隐藏从基类继承的成员 3 n
  • 水文数据产品的网站

    主要记录在平常用到的水文数据产品的网站 包括水库 湖泊 河流等 1 hydroweb 官网 https www theia land fr en hydroweb 界面 下载后的数据是txt格式 如需转成csv 可这样批量操作 import
  • React hooks中ref、forwardRef、useImperativeHandle的结合使用

    ref 用来绑定到HTML元素或者组件上 获取其DOM forwardRef 帮助子组件拿到父组件中子组件上面绑定的ref 绑定到自己的某一个元素中 这样就将子组件的DOM直接暴露给了父组件 这种方式存在的弊端 1 直接暴露给父组件带来的问
  • Linux 查看目录和文件

    目录 1 显示当前目录 pwd 2 改变目录 cd 3 列出目录内容 ls 4 列出目录内容 dir和vdir 5 查看文本文件 cat和more 6 阅读文件的开头和结尾 head和tail 7 查找文件内容 grep 1 显示当前目录
  • 存储解决方案之——FC存储解决方案

    FC存储解决方案 一 需求分析 当前 在FC Fibre Channel 领域里鲜有新技术问世 很多技术都已经成为过去时 近来在技术上的演进就是从2Gbit s 到4Gbit s的过渡 而且基本上已经完成 基于光纤通道 FC 的存储局域网络
  • Win10中docker的安装与使用

    WIN10中DOCKER的安装与使用 WIN10中DOCKER的安装与使用 1 docker的安装 环境准备 下载安装 2 docker的入门 开始使用 3 docker的常用配置 在PowerShell中设置 tab键自动补全 其实用的都
  • 蓝牙设备中的Device UUID 与 Service UUID

    Device UUID也可以被称作为DeviceID Android 设备上扫描获取到的 deviceId 为外围设备的 MAC 地址 相对固定 iOS 设备上扫描获取到的 deviceId 是系统根据外围设备 MAC 地址及发现设备的时间
  • mysql的left join和inner join的效率对比,以及如何优化

    一 前言 最近在写代码的时候 遇到了需要多表连接的一个问题 初始sql类似于 select from a left join b on a x b x left join c on c y b y left join d on d z c
  • Idea项目如何打包

    项目代码打包 一 idea软件为例 二 打包前的准备 1 application yml修改 代码 第三行dev改为pro spring profiles active SPRING PROFILES ACTIVE dev activiti
  • thinkphp5.0 常量

    预定义常量 EXT 类库文件后缀 php THINK VERSION 框架版本号 路径常量 DS 当前系统的目录分隔符 THINK PATH 框架系统目录 D phpStudy WWW my tadmin thinkphp ROOT PAT
  • Hash映射理解

    先说数组 数组优点之一 能通过索引很快定位到值 hashmap 就是利用了数组这个优点 对比 线性映射 定义一个数组 数组的元素是结构体 结构体包括 一对键 值 伪代码表示 a 0 struct Bill 5 a 1 struct KK 6
  • 【Unity3d】Animator和Animation组件使用注意事项

    一 Animator一般用于人物动画控制 特点是动画是持续的 可能有动作切换 Animation一般用于间断性的动画的控制 比如一个场景特效的播放 只播放一次就完了 二 实测Animation速度比Animator快10 左右 内存占用没测
  • vue+高德地图 点击地图获取经纬度和详细地址

    html源码
  • docker什么命令启动服务?

    docker启动服务的命令是 1 启动 1 systemctl start docker 2 守护进程重启 1 sudo systemctl daemon reload 3 重启docker服务 1 systemctl restart do
  • HDLC原理及配置

    一 HDLC原理 HDLC是由国际标准化组织 ISO 制定的面向比特的同步数据链路层协议 主要用于封装同步串行链路上的数据 HDLC是在数据链路层中被广泛使用的协议之一 二 HDLC配置 AR1
  • 使用Qemu+gdb来调试内核

    原文地址 http blog csdn net iamljj article details 5655169 昨天听别人讲使用Qemu和gdb来实现源码级内核调试 今天试了一下 果然非常方便 现简单的记录一下 Qemu是一个开源的虚拟机软件