使用QEMU+GDB调试Linux内核
Linux下交叉编译gdb,gdbserver+gdb的使用以及通过gdb调试core文件
Linux下交叉编译gdb,gdbserver+gdb的使⽤以及通过gdb调试core⽂件交叉编译gdb和gdbserver$ tar jxvf gdb-7.2.tar.bz2注:⼩技巧:Linux下⼀般压缩⽂件后缀为.tar.bz2和.tar.gz,它们解压命令有两三个选项是⼀致的:xf(v),前者再加上j选项,后者再加上z选项。
3、进⼊该⽬录$ cd gdb-7.2/4、配置$./configure --target=arm-linux --program-prefix=arm-linux- --prefix=/usr/local/arm-gdb注:--target=arm-linux意思是说⽬标平台是运⾏于ARM体系结构的linux内核;--program-prefix=arm-linux-是指⽣成的可执⾏⽂件的前缀,⽐如arm-linux-gdb,--prefix是指⽣成的可执⾏⽂件安装在哪个⽬录,这个⽬录需要根据实际情况作选择。
如果该⽬录不存在,会⾃动创建,当然,权限⾜够的话。
5、编译、安装$ make$ make install幸运的话,会在--prefix指定的⽬录下⽣成三个⼦⽬录:bin、lib、share,我们需要的arm-linux-gdb就在其中的bin⽬录下。
如果你不⼩⼼查看它的⼤⼩的话,会发觉它有14MB那么⼤!天呐!怎么会占这么多空间?没关系,我们可以为它瘦⾝。
没错!就是使⽤strip命令!$ strip arm-linux-gdb -o arm-linux-gdb-stripped$ ls -lh总计 33M-rwxr-xr-x 1 latelee root 14M 12-14 16:16 arm-linux-gdb-rwxr-xr-x 1 latelee root 3.1M 12-14 16:25 arm-linux-gdb-stripped可以看到,strip后的⽂件⼤⼩只有3.1MB,瘦⾝效果明显!如果做⼴告的话,绝对有说服⼒。
Linux命令高级技巧使用gdb命令进行程序的调试与分析
Linux命令高级技巧使用gdb命令进行程序的调试与分析在Linux环境下,gdb(GNU调试器)是一个非常强大的工具,用于调试和分析程序的运行。
它提供了丰富的功能,能够帮助开发人员定位和解决程序中的错误。
本文将介绍一些使用gdb命令进行程序调试与分析的高级技巧。
一、安装gdb命令若系统中尚未安装gdb命令,可以通过以下方式安装:1. 打开终端窗口2. 输入命令“sudo apt-get install gdb”并按下回车键3. 输入用户密码并按下回车键4. 等待安装完成二、使用gdb调试程序调试程序是开发过程中非常重要的一环。
gdb提供了各种功能,可以帮助开发人员追踪代码的执行,查找变量的值,以及定位程序中的错误。
下面介绍一些常用的调试命令:1. 启动gdb调试使用命令“gdb <可执行文件>”启动gdb调试器,其中<可执行文件>是需要调试的程序的路径和文件名。
2. 设置断点在需要设置断点的代码行前面输入“break”命令,例如“break main”,即可在main函数入口处设置断点。
使用命令“info breakpoints”可以查看已设置的断点。
3. 运行程序输入“run”命令,即可开始运行程序。
程序运行到断点处会自动停止,等待用户进行调试操作。
4. 单步执行输入“next”命令可逐行执行程序,遇到函数调用时会直接跳过,并进入下一行。
若想进入函数内部进行调试,使用“step”命令。
5. 查看变量值使用“print <变量名>”命令可以查看变量的值,例如“print num”即可查看名为num的变量的值。
6. 修改变量值输入“set <变量名>=<新值>”命令可以修改变量的值,例如“setnum=10”即可将名为num的变量的值修改为10。
7. 继续执行使用“continue”命令可以让程序继续执行,直到遇到下一个断点或程序结束。
QEMU、GDB的安装及简单使用
2.4 实例—创建交叉编译环境1.从网上下载或使用开发板公司在附赠光盘中提供的交叉编译工具链(1)从网上下载arm-linux-gcc或arm-linux-tools压缩包(2)解压arm-linux-gcc-2.95.3.tar.bz2到/usr/local/arm/中# mkdir /usr/local/arm# tar -xjvf arm-linux-gcc-2.95.3.tar.bz2 -C /usr/local/arm/(u-boot)等。
(3)解压arm-linux-gcc-3.4.1.tar.bz2到/usr/local/arm/中# tar -xjvf arm-linux-gcc-3.4.1.tar.bz2 -C /BootLoader(u-boot)等。
在编译时如果所用的版本不行的话,可以试试其它的版本,可以在Makefile文件中指定。
(4)解压arm-linux-tools-20070808.tar.gz(4.2.1版本)# tar -xzvf arm-linux-tools-20070808.tar.gz -C /注意:经过上述安装步骤,本系统默认的arm-linux-gcc是arm-linux-gcc-4.2.1,如果要使用其它版本,可以在Makefile文件中指定。
2.5 实例—QEMU、GDB的安装及简单使用2.5.1 QEMU的安装1.在/下载QEMU最新版# wget /download/qemu-1.4.0.tar.bz2 2.解压qemu-1.4.0.tar.bz2# tar -xjvf qemu-1.4.0.tar.bz23.生成QEMU的Makefile# cd qemu-1.4.0# ./configure --target-list=arm-softmmu,arm-linux-user4.编译、安装QEMU# make -j 2 //双核的CPU# make install //命令安装在/usr/local/bin/5.查看QEMU版本6.查看QEMU命令2.5.2 GDB的安装1.在/software/gdb/下载GDB最新版# wget ftp:///pub/gdb/releases/gdb-7.5.1.tar.bz2 2.解压gdb-7.5.1.tar.bz2# tar -xjvf gdb-7.5.1.tar.bz23.生成GDB的Makefile# cd gdb-7.5.1# ./configure --target=arm-linux4.编译、安装GDB# make# make install两个命令安装在/usr/local/bin/:arm-linux-run、arm-linux-gdb。
[Linux学习gdb调试教程]
There is NO WARRANTY, to the extent permitted by law. Type
不应该怀疑代码而应该怀疑数据,因为第一次和第二次运行的都是同一段 "show copying"
代码,如果代码是错的,那为什么第一次的结果能对呢?然而第一次和第
and "show warranty" for details.
files -- Specifying and examining files
to "word".
internals -- Maintenance commands
Command name abbreviations are allowed if unambiguous.
在编译时要加上-g 选项,生成的可执行文件才能用 gdb 进行源码级 件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到
调试:
可执行文件中,所以在调试时必须保证 gdb 能找到源文件。gdb 提供一个
第 2 页 共 10 页
本文格式为 Word 版,下载可任意编辑,页眉双击删除即可。
第一个结果正确[20],第二个结果显然不正确,在小学我们就听说过
This is free software: you are free to ch的故事,从 1 加到 100 应该是 5050。一段代码,第一次运行 it.
结果是对的,第二次运行却不对,这是很常见的一类错误现象,这种情况
#include <stdio.h> int add_range(int low, int high) { int i, sum; for (i = low; i <= high; i++) sum = sum + i; return sum; } int main(void) { int result[100]; result[0] = add_range(1, 10); result[1] = add_range(1, 100); printf("result[0]=%d\nresult[1]=%d\n", result[0], result[1]); return 0;
6.1.1 QEMU运行ARM Linux内核[共3页]
第6章内核调试本章主要介绍一些内核调试的工具和技巧,以及内核开发者常用的调试工具,例如ftrace和systemtap等。
对于编写内核代码和驱动的读者来说,内存检测和死锁检测是不可避免的,特别是做产品开发,产品最终发布时要保证不能有越界访问等内存问题。
本章的最后会介绍一些内核调试的小技巧。
本章介绍的调试工具和方法大部分都在Ubuntu 16.04 + QEMU + ARM Vexpress平台上实验过。
6.1 QEMU调试Linux内核为了加速开发过程,ARM公司提供了Versatile Express开发平台,客户可以基于Versatile Express平台进行产品原型开发。
作为个人学习者,没有必要去购买Versatile Express 开发平台或其他ARM开发板,完全可以通过QEMU来模拟开发平台,同样可以达到学习的效果。
6.1.1 QEMU运行ARM Linux内核1.准备工具首先在Untuntu 16.04中安装如下工具。
$ sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build- essential下载如下代码包。
linux-4.0内核:https:///pub/linux/kernel/v4.x/linux-4.0.tar.gz。
busybox工具包:https:///downloads/busybox-1.24.0.tar.bz2。
2.编译最小文件系统首先利用busybox手工编译一个最小文件系统。
$ cd busybox$ export ARCH=arm$ export CROSS_COMPILE= arm-linux-gnueabi-$ make menuconfig进入menuconfig之后,配置成静态编译。
Busybox Settings --->Build Options --->[*] Build BusyBox as a static binary (no shared libs)。
Linux内核漏洞调试环境搭建
Linux内核漏洞调试环境搭建一.前言之前没怎么用过Linux,但是那天看到exploit-db上有不少Linux内核漏洞的POC。
当时想如果可以请自动手调试一下这些漏洞,肯定会学到一些Linux下特定漏洞的利用技巧。
(比如怎么利用空指针引用漏洞来进行本地提权)。
所以就GOOGLE了很多关于Linux内核调试的文章,虽然一步一步老老实实照前人的指点的做,但是还是问题连着问题。
反反复复的尝试,才历尽千心万苦搭建起了这个内核漏洞调试环境。
在此过程中得到了广大网友的帮助,特别是wzt85和塞(他的ID为塞)这两位前辈的指点。
既然取之于“网”,那我觉得应该把这个过程用文字描述出来放到网络上,与同道中人分享。
本文的第二部分将简单介绍目前Linux下内核调试的几种常用调试技术路线,由于我对Linux的了解确实不多,所以这一部分写的肯定会很不专业,但目的在于抛砖引玉——更专业的文章烦请自行GOOGLE。
本文的第三部分会详细介绍该调试环境的搭建过程,关键点会有截图说明。
本文的第四部分是一点补充性的文字。
二.Linux下内核调试技术路线1.QEMU+GDBQEMU是一款开源的虚拟机软件,它自身带有gdb stub可用于和Host 主机上的GDB通信来对Guest主机的Linux内核进行源码(C代码)级调试。
为实现源码级调试,那必须要有调试信息以及符号表,所以首先从上下载一份Linux内核源代码进行编译。
编译成功后会得到bzImage文件和vmlinux文件。
其中vmlinux就是要供Host主机上的GDB进行调试的带有调试信息,符号表的内核文件。
使用这种方法试验环境的搭建比较简单,而且最吸引人的地方在于它能够实现源码级的调试。
但是遗憾的是,这种方法调试不了漏洞。
因为当Guest主机上的内核发生内存访问异常的时候,Host主机中的GDB根本得不到异常事件,这样一来也就无法获知是那条指令引发的异常,以及被访问的内存地址是什么。
Linux内核调试
0x00 前言这段时间开始学习了linux内核提权,也跟进看了一些漏洞。
但是由于linux系统版本、内核版本的不同,驱动模块或者是某个函数的加载地址都是不同的,如果不能自己亲自调试内核,就算给了exp也是无法利用。
之前也没有怎么接触过内核调试,所以这几天找了许多资料开始学习调试内核的方法,总结整理在这。
本文测试系统是Ubuntu12.04 64位。
0x01 准备环境首先当然是准备需要调试的内核版本,linux的所有历史版本都可以在这里找到。
down下来后进入源码树根目录,开始配置内核,这里使用基于ncurse库编制的图形界面工具:$ make menuconfig由于我们需要使用kgdb调试内核,注意下面这几项一定要配置好:KernelHacking -->选中Compile the kernel with debug info选中Compile the kernel with frame pointers选中KGDB:kernel debugging with remote gdb,其下的全部都选中。
Processor type and features-->去掉Paravirtualized guest supportKernelHacking-->去掉Writeprotect kernel read-only data structures(否则不能用软件断点)保存config文件之后make、make modules_install、make install编译安装就好。
具体安装编译内核可以看我另一篇笔记0x02 使用kvm、gdb调试内核先介绍一下现在用得比较多的调试内核方法吧,简单地说就是在linux系统里再装一个kvm虚拟机配置好gdb远程调试支持,然后在linux主机上连接调试。
但是我因为电脑配置不高,装了kvm太卡就放弃了这个方法orz总之还是讲一下怎么调试吧。
使用QEMU+GDB调试Linux内核
使用QEMU调试Linux内核一.使用QEMU安装Ubuntu10.041.安装qemuubuntu下使用sudo apt-get install 安装的qemu版本是0.12.3,该版本中存在bug,使得无法在断点处停下;因此需要在qemu官方网站/Download上下载最新的版本qemu-0.12.5.tar.gz的源代码包自己进行编译安装:●Sudo apt-get install zlib1g-dev libsdl-dev●解压源代码后,进入源代码所在目录执行./confingure●执行make●执行sudo make install2.创建QEMU格式的硬盘qemu-img create –f qcow2name.img size例如:qemu-img create –f qcow2 ubuntu10.04.img 4GB3.在创建的硬盘上安装操作系统qemu–hdaname.img–cdrom ~/Download/ubuntu10.04.iso –boot d 说明:使用hda指定硬盘镜像,使用CDROM选定光驱。
-boot d 指从cdrom启动,-boot a是软盘,-boot c 是硬盘;使用qemu或qemu-system-x86_64(64为机子),有时安装系统会很慢,这是可以考虑使用kvm来代替。
例如:kvm–hda ubuntu10.04.img –cdrom ./ubuntu-10.04.iso -bootd4.从已经装好操作系统的硬盘启动qemu–hda ubuntu10.04.img5.在64位的主机上要使用qemu-system-x86_64命令来代替qemu 二.自己编译内核现将Linux的编译调节过程简述为:1. 下载自己要调试的Linux内核的源代码,这个可以从Linux内核的官方网站上得到:2. 编译内核最主要的便是配置文件.config,为了能够准确的得到结果(第一次不要求编译时间),将本机的config文件直接拷贝到解压后的源代码中。
linux gdb调试指令 linux下gdb常用的调试指令
u 内存单位(b: 1 字节; h: 2 字节; w: 4 字节; g: 8 字节)
set print address on
set vairiable a = 100 可以修改变量的值
打开地址输出,当程序显示函数信息时,GDB 会显出函数的参数地址。
commands 指定到了特定断点后is buf 显示变量的类型
set print object <on/off>
dump memory 输出文件名 内存起始地址 内存终止地址
在 C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB
restore 文件名 binary 起始位置
会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB 就
delete 删除断点 d 3 删除指定的断点 condition 修改条件 condition 4 a == 90 info 查看信息 info threads 查看线程信息 info breakpoints 查看断点信息 info locals 显示局部变量 info args 显示函数变量 info registers 显示寄存器数据 thread 2 切换线程 where 查看调用堆栈(bt 或者 info s)
set print elements 0 默认这里设置是 200,设置为 0 表示没有限
x/nfu 0×300098 显示指定地址的内存数据
制
n 显示内存单位,长度
还有其它一些 set 命令可以试试:
f 格式(除了 print 格式外,还有 字符串 s 和 汇编 i)
set print address
break 设置断点 b main 设置函数断点 b 9 设置指定行断点 b 将下一行设置为断点 b test if a == 10 设置条件断点
Linux下core文件调试方法
Linux下core⽂件调试⽅法在程序不寻常退出时,内核会在当前⼯作⽬录下⽣成⼀个core⽂件(是⼀个内存映像,同时加上调试信息)。
使⽤gdb来查看core⽂件,可以指⽰出导致程序出错的代码所在⽂件和⾏数。
1.core⽂件的⽣成开关和⼤⼩限制(1)使⽤ulimit -c命令可查看core⽂件的⽣成开关。
若结果为0,则表⽰关闭了此功能,不会⽣成core⽂件。
通过上⾯的命令修改后,⼀般都只是对当前会话起作⽤,当你下次重新登录后,还是要重新输⼊上⾯的命令,所以很⿇烦。
我们可以把通过修改 /etc/profile⽂件来使系统每次⾃动打开。
步骤如下:1.⾸先打开/etc/profile⽂件⼀般都可以在⽂件中找到这句语句:ulimit -S -c 0 > /dev/null 2>&1.ok,根据上⾯的例⼦,我们只要把那个0 改为 unlimited 就ok了。
然后保存退出。
2.通过source /etc/profile 使当期设置⽣效。
3.通过ulimit -c 查看下是否已经打开。
其实不光这个命令可以加⼊到/etc/profile⽂件中,⼀些其他我们需要每次登录都⽣效的都可以加⼊到此⽂件中,因为登录时linux都会加载此⽂件。
⽐如⼀些环境变量的设置。
还有⼀种⽅法可以通过修改/etc/security/limits.conf⽂件来设置,⾸先以root权限登陆,然后打开/etc/security/limits.conf⽂件,进⾏配置:#vim /etc/security/limits.conf<domain> <type> <item> <value>* soft core unlimited(2)使⽤ulimit -c filesize命令,可以限制core⽂件的⼤⼩(filesize的单位为kbyte)。
若ulimit -c unlimited,则表⽰core⽂件的⼤⼩不受限制。
使用Qemu+gdb来调试内核
使用Qemu+gdb来调试内核昨天听别人讲使用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虚拟机的执行,从而达到调试的目的。
linux系统调试工具GDB 命令详细解释..
Linux中包含有一个很有用的调试工具--gdb(GNU Debuger),它可以用来调试C和C++程序,功能不亚于Windows下的许多图形界面的调试工具。
和所有常用的调试工具一样,gdb提供了以下功能:# 监视程序中变量的值# 在程序中设置断点# 程序的单步执行在使用gdb前,必须先载入可执行文件,因为要进行调试,文件中就必须包含调试信息,所以在用gcc或cc编译时就需要用-g参数来打开程序的调试选项。
调试开始时,必须先载入要进行调试的程序,可以用以下两种方式:* 在启动gdb后执行以下命令:file 可执行文件路径* 在gdb启动时就载入程序:gdb 可执行文件路径载入程序后,接下来就是要进行断点的设置,要监视的变量的添加等工作,下面对在这个过程中常会用到的命令逐一进行介绍:* list:显示程序中的代码,常用使用格式有:list输出从上次调用list命令开始往后的10行程序代码。
list -输出从上次调用list命令开始往前的10行程序代码。
list n输出第n行附近的10行程序代码。
list function输出函数function前后的10行程序代码。
* forward/search:从当前行向后查找匹配某个字符串的程序行。
使用格式:forward/search 字符串查找到的行号将保存在$_变量中,可以用print $_命令来查看。
* reverse-search:和forward/search相反,向前查找字符串。
使用格式同上。
* break:在程序中设置断点,当程序运行到指定行上时,会暂停执行。
使用格式:break 要设置断点的行号* tbreak:设置临时断点,在设置之后只起作用一次。
使用格式:tbreak 要设置临时断点的行号* clear:和break相反,clear用于清除断点。
使用格式:clear 要清除的断点所在的行号* run:启动程序,在run后面带上参数可以传递给正在调试的程序。
使用qemu进行内核源码级调试
使用qemu进行内核源码级调试内核源码调试对于内核初学者而言是一件有一定难度的事.工欲善其事,必先利其器,要想成功地进行内核源码级的调试,首先,必须现找到一个合适的工具,下面,笔者就来介绍内核源码调试的一款工具QEMU.QEMU是一个通用并开放源代码的模拟器,其功能相当的强大,例如:可以用QEMU来模拟一个完整的系统,同时,也可以用QEMU来实现系统源码级的调试.如果您想对QEMU仿真器有更加深入的了解,请参阅其官方网站:/下面笔者从如何得到QEMU,以及如何在linux下安装QEMU并进行源码级的调试做一个详细的介绍.(一) qemu的获得以及安装得到qemu是相当方便的,到其官方网站/qemu/download.html下载QEMU Linux下载最新版本即可.接下来是在linux下安装qemu的详细步骤:第一步:把下载的文件放到工作目录下,解压缩:例如:huanghucai@huanghucai-laptop:~/kernel_learning$ tar zxvfqemu-0.10.5.tar.gz第二步:切换到qemu目录下huanghucai@huanghucai-laptop:~/kernel_learning$ cdqemu-0.10.5第三步:配置安装huanghucai@huanghucai-laptop:~/kernel_learning/qemu-0.10.5$ ./configurehuanghucai@huanghucai-laptop:~/kernel_learning/qemu-0.10.5$ sudo makehuanghucai@huanghucai-laptop:~/kernel_learning/qemu-0.10.5$ sudo make install这样,qemu就安装好了,安装好了之后,对于一个新的软件,我们需要查看其具体的使用方法,那么请查看它的man手册.或者是到其官方网站去了解其基本的应用.(二) 使用QEMU进行内核源码级调试接下来,就是利用QEMU进行内核源码调试.要想在QEMU下进行内核源码调试,和其他内核调试方式一样,首先是准备内核镜像.为了能够进行源码级的跟踪、调试,需要一个包含调试信息的内核镜像.下面将会以linux-2.6.23.2内核版本为例来进行讲解.首先是到linux内核官方网站获得linux-2.6.23.2内核源码linux-2.6.23.2.tar.gz,下载后解压缩,将源代码放到工作目录下,例如:放到目录huanghucai@huanghucai-laptop:~/kernel_learning$(这里说点题外话,这里笔者推荐一款下载工具axel,下载速度很快的,为了尽快的得到源代码,安装axel,复制链接,之后终端执行下面命令:axel -n 50 -o ./pub/linux/kernel/v2.6/linux-2.6.23.2.tar.gz 不过60秒,你就可以得到linux内核源码了,上面的.表示你把下载源代码放在了当前工作目录下,使用了50线程,要想对axel有深入的了解,你可以man一下就OK了)下载内核源代码之后,解压缩,并进入内核源码目录:huanghucai@huanghucai-laptop:~/kernel_learning$ tar zxvflinux-2.6.23.2 linux-2.6.23.2.tar.gzhuanghucai@huanghucai-laptop:~/kernel_learning$ cdlinux-2.6.23.2第一步、生成新的.config文件,其中的配置采用默认的选项就可以了huanghucai@huanghucai-laptop:~/kernel_learning/linux-2.6.23.2$ defconfig第二步、修改已有的.config文件,在这个步骤中,添加新的内核选项huanghucai@huanghucai-laptop:~/kernel_learning/linux-2.6.23.2$ make memuconfig进入顶级选项Kernel hacking选项,选中kernel debugging,之后再次选中Compile kernel with debug info选项,选择以后出来并保存就可以了;第三步、创建大内核镜像bzImagehuanghucai@huanghucai-laptop:~/kernel_learning/linux-2.6.23.2$ make bzImage第三步运行结束需要较长的时间,当第三步完成之后,如果没有出现什么问题,就可以直接略去下面的这些内容跳到第四步就OK了;如果你使用的是gcc 4.3,那么很有可能会出现创建失败的情况,错误提示如下所示: ............LD .tmp_vmlinux1kernel/built-in.o: In function `getnstimeofday':(.text+0x1b2b1): undefined reference to `__umoddi3'kernel/built-in.o: In function `do_gettimeofday':(.text+0x1b36c): undefined reference to `__udivdi3'kernel/built-in.o: In function `do_gettimeofday':(.text+0x1b38f): undefined reference to `__umoddi3'kernel/built-in.o: In function `timekeeping_resume': timekeeping.c:(.text+0x1b520): undefined reference to `__udivdi3' timekeeping.c:(.text+0x1b543): undefined reference to`__umoddi3'kernel/built-in.o: In function `update_wall_time':(.text+0x1bb9d): undefined reference to `__udivdi3'kernel/built-in.o: In function `update_wall_time':(.text+0x1bbc0): undefined reference to `__umoddi3'kernel/built-in.o: In function `update_wall_time':(.text+0x1bc57): undefined reference to `__udivdi3'kernel/built-in.o: In function `update_wall_time':(.text+0x1bc81): undefined reference to `__umoddi3'make: *** [.tmp_vmlinux1] Error 1这个错误的原因是因为gcc 4.3在处理64位整数运算的时候出现的问题,解决的办法据我所知有两种,这里介绍其中一种.在linux2.6.23.2目录下的Makefile文件中给变量CFLAGS_KERNEL赋值为:-fno-tree-scev-cprop,改变值之后重新编译一次就OK了.如果出现了undefined reference to`__stack_chk_fail',可以在文件Makefile中的CFLAGS设置值-fno-stack-protector,即关闭掉栈的保护.如果出现其他编译失败的情况,你可以借助于google找到相关的解决方案.第四步就是准备根文件系统镜像,这里我从qemu的官方网站下载了linux-0.2.img.bz2,解压缩并将解压缩后的文件放到源代码目录下.经过上面四个步骤的工作,现在你已经将内核源码级的调试环境搭建完了,下一步就来进入qemu下的内核源码级调试.(三) QEMU下内核源码级调试首先是启动qemu:可以运行类似于下面命令来启动qemu:qemu -S -kernel arch/i386/boot/bzImage -hda linux-0.2.img-append "root = dev/hda" -no-kqemu截图如下所示:使用qemu进行内核源码级调试(错误解决办法):操作平台:vmware6.0+ubuntu11.04+qemu-0.14.1+linux-2.6.23.2.tar.gz1.defconfig命令不对,应该是make defconfig2.make menuconfig错误,原因是缺少ncurses。
Eclipse CDT + QEMU调试linux内核
Eclipse CDT + QEMU调试linux内核本篇有关系统环境我要交代一下。
因为在ubuntu下找不到eclipse cdt的源,所以要先apt-get 一个eclipse paltform然后在里面选择更新安装cdt才能安装成功。
但在eclipse platform 里更新比较容易失败,所以我推荐大家安装opensuse 11.0,在这里面只要到下载一个eclipse c/c++ ide ,直接解压便可运行。
文章开始!1.首先我们要从下载内核源码,在这里我选择的是linux-2.6.28.tar.bz2。
我将其下载到我的主目录下,然后在xterm下输入以下命令。
$ cd (回到主目录)$ tar xf linux-2.6.28.tar.bz2 (解压源码)$ mkdir linux-2.6.28-obj (创建一个编译内核的目标文件输出目录)$ cd linux-2.6.28 (进入内核源码树根目录)$ make O=/home/xxx/linux-2.6.28-obj menuconfig (这里我们要配置内核,并在~/linux-2.6.28-obj目录下生成内核配置文件.config) (注意:这里的xxx表示的是你的用户名) 注意在这里我们要选择kernel hacking 配置菜单下的“Compile the kernel with debug info”和“Compile the kernel with frame pointers”如下图:2. 接下来我们打开elicpse,第一次打开时有一个欢迎画面,我们单击右边的workbench图片关掉欢迎画面。
由于eclipse cdt是一个非常强大的c/c++ ide,它默认会自动的解析工程中源程序并编译工程和产生智能提示信息。
但由于我们调试内核过程中暂不会用到这些功能,所以要关闭他们。
首先我们到Window->Preferences->General->Workspace 中将Build Automatically选项去掉。
使用GDB调试Linux软件
使用GDB调试Linux软件GNU调试器介绍绝大部分Linux爱好者在shell中使用GNU调试器或者叫做gdb。
Gdb让您能够看到一个程序的内部结构,指出变量的值,设置断点并在源码中进行单步执行。
它是一个解决代码中的问题的非常好的工具。
在这篇文章中,我将告诉您这个工具有多么酷和多么有用。
编译在您开始之前,您要调试的程序必须先进行编译,并把调试信息编译进去。
这样gdb才能找到变量、代码行和函数。
要做到这一点,只要在使用gcc(或g++)编译的时候额外加一个“-g”的属性即可,如:gcc -g -o eg运行gdbGdb从shell运行,使用命令“gdb”,后面跟上程序名字作为参数,例如“gdb eg”,或者您可以使用file命令加载一个程序用于调试,如“file eg”。
这两种方法都假定您是在程序所在的文件下执行命令的。
一旦加载成功,就可以在gdb中使用“run”命令来启动程序了。
调试例子如果没有任何错误您的程序会完成执行,在某个点上gdb可以获得控制权。
但是如果出错了呢?这种情况下gdb会取得控制权并中断程序,允许您检查每一样东西的状态并有希望找到原因。
为了表现这一场景,我们使用一个例子程序:#includeint wib(int no1, int no2){int result, diff;diff = no1 - no2;result = no1 / diff;return result;}int main(int argc, char *argv[]){int value, div, result, i, total;value = 10;div = 6;total = 0;for(i = 0; i < 10; i++){result = wib(value, div);total += result;div++;value--;}printf("%d wibed by %d equals %d\n", value, div, total);return 0;}这个程序运行10次循环,使用函数wib()计算一个累加值,最后打印出结果。
QEMU+GDB调试方法
QEMU+GDB调试⽅法两年前调试usb/ip开源项⽬时,就曾⽤虚拟机远程调试过Windows和Linux系统内核,当时在VMware Workstation上创建两个虚拟机进⾏调试,也没有记录下如何配置调试,只是⼤体的还记得。
好久没⽤GDB了,今天下载了QEMU源码,编译安装后想调试⼀下,前前后后花了⼤概⼀个⼩时才弄懂怎么调试QEMU,在此做个记录备忘。
个⼈认为⽤GDB调试QEMU时调试⽬标分为两种,⼀种是⽤GDB调试由QEMU启动的虚拟机,即远程调试虚拟机系统内核,可以从虚拟机的bootloader开始调试虚拟机启动过程,另⼀种是调试QEMU本⾝的代码⽽不是虚拟机要运⾏的代码。
为了分析学习QEMU的源代码,我当然要进⾏后⼀种调试,但在这⾥我把两种调试的⽅法都说明⼀下:1. 调试QEMU虚拟机内核:镜像⽂件是test1.qcow2,上述命令⾏中,-S表⽰“freeze CPU at start up”,所以运⾏后你看不到任何输出。
打开另⼀个console,运⾏gdb命令,如下图:然后在GDB内部执⾏“target remote localhost:1234”,1234是默认的远程⽤于调试连接的端⼝号。
然后执⾏命令“break*0x7c00”,这样就将⼀个断点设置在了bootloader被加载到的内存地址,接下来就任你玩了。
2. 调试QEMU源码:⽤上述命令启动/usr/local/bin/qemu-system-x86_64,然后来到GDB命令⾏输⼊界⾯,如下图:执⾏“break main”,和“break qemu_init_cpu_loop”,就在这两个函数的开始处分别设置了⼀个断点。
然后执⾏“start”命令,看到运⾏到第⼀个断点处停了下来,执⾏“c”继续运⾏,⼜碰到了第⼆个断点,执⾏“bt”看⼀下调⽤栈,确实调⽤到了qemu_init_cpu_loop函数。
如果想看源代码,执⾏“layout src”执⾏,就出现了如上图所⽰的源码窗⼝,接下来,随便你玩了。
Linux命令高级技巧使用gdb命令进行程序调试和分析
Linux命令高级技巧使用gdb命令进行程序调试和分析在Linux环境中,gdb是程序员们常用的工具之一,用于调试和分析程序。
gdb是GNU调试器的缩写,它提供了多种功能和选项,能够帮助程序员追踪程序的执行过程,找出错误并进行修复。
本文将介绍一些使用gdb进行程序调试和分析的高级技巧,希望能对读者有所帮助。
一、gdb简介gdb是一个功能强大的调试工具,它可以在程序执行过程中暂停程序,并允许程序员查看、修改程序状态。
gdb支持多种编程语言,包括C、C++、Fortran等。
使用gdb可以帮助程序员分析程序的执行流程、内存使用情况以及变量状态等,从而帮助定位并解决程序的bug。
二、基本调试技巧1. 启动程序调试使用gdb调试程序时,需要在命令行中输入"gdb 程序名"的命令来启动gdb。
例如,要调试一个名为"test"的程序,可以输入以下命令:```gdb test```2. 设置断点断点是gdb中非常有用的功能,可以在程序中指定位置设置断点,使程序执行到该位置时暂停。
通过暂停程序的执行,可以查看程序中的变量值以及执行流程,有助于定位问题。
设置断点的命令是"break"或"b",后跟着要设置断点的位置。
例如,要在程序的第10行设置断点,可以输入以下命令:```break 10```3. 执行程序在设置好断点后,可以使用"gdb"命令来开始执行程序。
程序将会运行到第一个断点处暂停。
4. 单步执行单步执行是gdb中常用的调试技巧之一,可以逐行执行程序,方便查看程序的执行过程。
gdb提供了多种单步执行的命令,包括"step"和"next"。
- "step"命令用于逐行执行程序,包括进入函数内部。
如果当前行是函数调用语句,gdb将进入该函数,然后停在函数内部的第一行。
debug Eclipse cdt + Qemu虚拟机调试Linux内核
A screencast demonstrating roughly the same thing is available at: /file/586651 For iTunes users there's a videopodcast at: /rss/itunes/ Download the Linux kernel sourcecode from /. For example, the current kernel version is 2.6.23, a direct link would be /pub/linux/kernel/v2.6/linux-2.6.23.9.tar.bz2 Extract the Linux kernel sourcecode: cd /usr/local/src tar xvjf linux-2.6.23.9.tar.bz2 We will build the Linux kernel in a different directory: mkdir -p /mnt/build/linux-2.6 Then copy the provided kernel configuration into this directory giving it a new name ".config". The following commands will then use this as a base-configuration to start from.Next, we'll configure the kernel. Just keep pressing enter to use the default answers to all the questions that the kernel configuration program will ask you. cd /usr/local/src/linux-2.6.23 make oldconfig O=/mnt/build/linux-2.6Next, make the kernel a bit easier to debug: make menuconfig O=/mnt/build/linux-2.6And enable the following options: In the "Kernel hacking" menu enable both "Compile the kernel with debug info" and "Compile the kernel with frame pointers". Now, we'll fire up Eclipse with the CDT plugin. You can download Eclipse with the CDT plugin from /downloads/You'll need to download "Eclipse IDE for C/C++ Developers".Get rid of the intro screen. You'll get an empty workspace as shown in the screenshot. First disable automatic building, by using the "Window->Preferences" menu, selecting "General->Workspace" and deselecting "Build automatically". Eclipse will perform a time consuming indexing operation which you can disable by using the "Window->Preferences" menu, selecting "C/C++->Indexer" and switching from "Fast C/C++ Indexer" to "No Indexer".Start a new project, by using File->New->Project... Then select "C Project", "Makefile project", "Empty Project".Now enter a project name and specify a specific directory for the project sourcecode. To do this, first uncheck the "Use default location" checkbox.Finally click "Finish".If you hadn't disabled indexing, Eclipse will now start indexing the Linux kernel sourcecode. This will take a long time.You'll see a progressbar which might give you an indication on how long it might take to complete.Eclipse finished indexing the kernel sourcecode. Now, we're ready to configure our debugger. Right-click on the project-name in the left pane (Project explorer) and select "Properties".We want to modify the default build command and the location where the build files should go.Uncheck "Use default build command" and enter make CC=gcc-3.4 O=/mnt/build/linux-2.6Modify the build location by clicking the "File system..." button and browsing to /mnt/build/linux-2.6Through the menu-bar select "Project->Build all" or press "Ctrl-b".After some time the Linux kernel build will be completed and you see "bzImage is ready" appear in the Eclipse Console output.Next, we'll run our kernel binary using the Qemu system emulator. The nice thing about Qemu is that besides the normal virtual HD, floppy and ISO image booting, it can also boot Linux kernels directly. And, Qemu provides a GDB-stub to which we can connect from our Eclipse debugger. The "-s" switch activates this GDB-stub. The "-S" switch makes sure Qemu doesn't start running before we're ready (it freezes the CPU at startup).Because the CPU is "frozen" at startup, the Qemu window won't show anything useful yet.Through the menubar, select "Run->Debug Configurations...". Double-click "C/C++ Local Application". Modify the "C/C++ Application" textentry to point to the actual Linux kernel, being /mnt/build/linux-2.6/vmlinuxClick on the "Debugger" tab, and in the "Debugger" listbox select the "gdbserver Debugger". Next, modify the "Stop on startup at:" to "start_kernel". Below this, you'll notice a frame named "Debugger Options"; click the "Connection" tab in this frame and modify the "Type" to "TCP" and the "Port number" to 1234. Continue by clicking the "Debug" button.Eclipse might compile and link a bit, but will finally launch the debugger and ask if you want to switch to the debugging perspective. Say yes.The next screenshot shows the debugging perspective. Just like with normal applications, you'll see that the line it is about the execute is highlighted.In the Qemu window, you'll notice some output already. This is the output which happened in functions preceding the start_kernel() function....By using "Run->Step over" or pressing the "F6" key, you can execute the kernel code line by line and examine what's happening.If you want to see the assembly instructions which are being executed, you can add a view which displays this by selecting "Windows->Show View->Disassembly".There's a register view too, as can be seen in the next screenshot. Registers who's contents has been altered by the previous execution step are highlighted in yellow.You can add breakpoints, inspect variables, inspect memory and much more, but as you keep running the kernel you'll run in trouble as we did not specify a true harddisk image for Qemu. So, you'll get the following output in the Qemu window, because the Linux kernel could not find a root filesystem on our fake harddisk image "/dev/zero".That's it. Hopefully the above is useful (and fun) for anyone :)。
高级操作系统实验-1-使用gdb调试qume
⾼级操作系统实验-1-使⽤gdb调试qume查看run脚本cat run可以看到,使⽤的内核为: qemu-system-i386 -nographic -kernel $LINUX/arch/i386/boot/bzImage,使⽤的硬盘为:-initrd rootfs/rootfs.img.gz如果在启动时加“-s”可以启动调试模式运⾏run,进⼊虚拟机./run(退出qume虚拟机:reboot -f)查看bin⽂件,如下图,可以看到,只有busybox是有效的⼆进制可执⾏⽂件,其他的都是对busybox的符号链接。
busybox在执⾏的时候,敲任何命令,结果都是在执⾏busybox。
退出虚拟机,⽤调试模式重新打开再建⼀个终端操作。
建⽴符号链接cur指向ubuntu中的内核源码,并查看内核根⽬录。
就不⽤把⼤⽂件放到虚拟机了,速度会受影响。
左边启动虚拟机,等待调试。
右边打开gdb调试器,从内核源码⾥⾯读取符号。
⽤gdb连接到qume虚拟机。
target remote localhost:1234把busybox可执⾏⽂件读进来,后⾯是起始地址。
加断点,这是执⾏命令解释器时候的⼊⼝。
ash_main再加ls命令的断点。
如下图右侧执⾏c,左侧即开始运⾏显⽰当前进程的进程号display $lx_current().pid查看当前进程是由哪个可执⾏⽂件引发的。
继续执⾏,看到964号进程⼜执⾏了命令解释器。
可见,启动过程中,ash_main执⾏了两次,在两个进程中运⾏的。
⽤strace查看ls执⾏的系统调⽤,新开⼀个终端。
上⾯是Ubuntu下执⾏的系统调⽤,那么虚拟机的呢,内核版本不⼀样,故执⾏的系统调⽤也不⼀样。
在系统调⽤的总控函数位置设置⼀个断点。
b entry_SYSENTER_32系统调⽤的实现函数进⾏跳转的时候,看看是哪个系统调⽤,也设⼀个断点跳转到系统调⽤实现函数的数组,包含的是系统调⽤实现函数的⼊⼝地址,所以只需要往前⾛⼀步,s,就会进⼊到相应的实现函数,可以看到,第⼀个实现函数是time继续执⾏,⾛⼀步到主控函数的⼊⼝,再⾛⼀步到跳转,再单步执⾏,重新回到系统调⽤实现函数。
使用gdb调试linux下的程序解析
使用GDB调试Linux应用程序版本:Rev1.02009-04更新记录2009.04.29文档创建。
使用GDB调试Linux应用程序Team MCUZone 本文演示使用GDB调试本站ARM开发板上的Linux应用程序的过程。
包含源程序编译,GDB,DDD,insight的使用。
调试器与开发板使用网络连接。
PC上的Linux发行版本选择Ubuntu8.10。
一,准备工作1.在开发板上建立Linux运行环境启动。
制作根的使用如下命令编译:注意其中的-g参数,指明生成debug信息。
将生成的dbgtst文件复制到rootfs的目录下,比如/usr/testapp。
启动开发板,以NFS方式mount根文件系统(rootfs。
本文档中开发板的IP为192.168.1.100,Linux server的IP为192.168.1.5。
三,使用GDB从arm-none-linux-gnueabi的工具链相应目录下复制gdbserver到开发板:将其放到开发板的/usr/bin下:在开发板上运行gdbserver:此时gdbserver将在2345端口等待远端连接。
切换到Linux server上,运行arm-none-linux-gnueabi-gdb:通过arm-none-linux-gnueabi-gdb dbgtst启动命令行调试器,在(gdb提示符下运行命令target remote 192.168.1.100:2345将连接到开发板的gdbserver,下面就可以用gdb 的命令开始调试。
例如l命令列出源代码:使用b命令设置断点:使用c运行程序:再次设置断点:使用n单步运行:使用p打印变量:由于优化的原因,不是所有的变量都可以通过p查看。
调试结束,通过disconnect断开gdbserver的连接,停止调试,并使用q退出gdb:开发板上的gdbserver也有相应提示:在命令行下,也可以使用arm-none-linux-gnueabi-gdbtui,运行起来后如下图:窗口上方会有代码的显示,下面仍然是命令行方式操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用QEMU调试Linux内核
一.使用QEMU安装Ubuntu10.04
1.安装qemu
ubuntu下使用sudo apt-get install 安装的qemu版本是0.12.3,该版本中存在bug,使得无法在断点处停下;因此需要在qemu官方网站/Download上下载最新的版本qemu-0.12.5.tar.gz的源代码包自己进行编译安装:
●Sudo apt-get install zlib1g-dev libsdl-dev
●解压源代码后,进入源代码所在目录执行./confingure
●执行make
●执行sudo make install
2.创建QEMU格式的硬盘
qemu-img create –f qcow2name.img size
例如:qemu-img create –f qcow2 ubuntu10.04.img 4GB
3.在创建的硬盘上安装操作系统
qemu–hdaname.img–cdrom ~/Download/ubuntu10.04.iso –boot d 说明:使用hda指定硬盘镜像,使用CDROM选定光驱。
-boot d 指从cdrom启动,-boot a是软盘,-boot c 是硬盘;使用qemu或qemu-system-x86_64(64为机子),有时安装系统会很慢,这是可以考虑使用kvm来代替。
例如:kvm–hda ubuntu10.04.img –cdrom ./ubuntu-10.04.iso -boot
d
4.从已经装好操作系统的硬盘启动
qemu–hda ubuntu10.04.img
5.在64位的主机上要使用qemu-system-x86_64命令来代替qemu 二.自己编译内核
现将Linux的编译调节过程简述为:
1. 下载自己要调试的Linux内核的源代码,这个可以从Linux内
核的官方网站上得到:
2. 编译内核最主要的便是配置文件.config,为了能够准确的得到
结果(第一次不要求编译时间),将本机的config文件直接拷
贝到解压后的源代码中。
3.然后进行make操作,结束后将产生的bzImage文件拷到boot
目录下,重启,选择自己编译的内核,这样一般不会出问题,但时间较慢,大约编译一次需要40分钟。
3.1以前编译内核是为调试内核服务的,现在做华为的项目,
发现需要在实际的机器上运行自己编译的内核,参考网站:
/tips/compiling-linux-kernel-26.html
4.为了降低编译时间,就需要对配置文件进行裁剪,在配置文件
中有好多是本机不需要的模块,参考:
/Linux/kernel_options.html。
另外调试内
核与模块无关,所以辨识为M的直接可以不选。
5.剪裁的时候采用“逐步瘦身”法,先剪裁掉某个或某几个模块,
然后在进行编译,若没错,在进行模块裁剪,这样可以最大程
度上保证内核配置的正确性。
6.使用qemu调试需要在编译内核的时候将调试信息添加上,
make menuconfig->kernel hacking->kernel debugging->compile
the kernel with debug info。
三.使用qemu+gdb调试Linux内核
(1)qemu–s –S –hda ./ubuntu10.04.img
–kernel ./arch/x86/boot/bzImage–append root=/dev/sda
-s表示运行虚拟机时将1234端口开启成调试端口;
-S表示“冷冻”虚拟机,等待调试器发出继续运行命令;
-kernel表示要调试的内核镜像;
-append root=/dev/sda表示传递给内核的参数。
(2)在另一个终端上运行gdb命令
gdbvmlinux
target remote localhost:1234
若到此没什么问题,你就可以发挥自己的聪明才智进行内核源代码的调试了。
四.GDB基本命令
1.list
/old-gnu/Manuals/gdb-5.1.1/html_node/gdb_46.html
2.GDB command
/TUTORIALS/GDB-Commands.html。