ubuntu安装systemtap
由于发行版的内核默认无内核调试信息,所以需要一个调试内核镜像,在http://ddebs.ubuntu.com/pool/main/l/linux-lts-wily/。找到内核版本相对应的内核调试镜像(版本号包括后面的发布次数、硬件体系等都必须一致),如针对我上面的内核版本,就可以用如下命令下载安装内核调试镜像:dpkg -i linux-image-4.2.0-42-generic-dbgs
·
由于发行版的内核默认无内核调试信息,所以需要一个调试内核镜像,在http://ddebs.ubuntu.com/pool/main/l/linux-lts-wily/。找到内核版本相对应的内核调试镜像(版本号包括后面的发布次数、硬件体系等都必须一致),如针对我上面的内核版本,就可以用如下命令下载安装内核调试镜像:
dpkg -i linux-image-4.2.0-42-generic-dbgsym_4.2.0-42.49-14.04.1_amd64.ddeb
一般这种方法下,你只需要使用apt在线安装systemtap即可:
$sudo apt-get install systemtap
寻找到正确的内核版本,执行这个,看到版本信息是
cat /proc/version_signature
uname -r
stap -e 'probe kernel.
function
(
"sys_open"
) {log(
"hello world"
)
exit
()}'
对应的systemtap简单脚本test.tsp如下:
probe udp.sendmsg {
if ( dport == 1234 ) {
printf("send to the port 1234 is PID %d ,process name is %s",pid(),execname())
}
}
if ( dport == 1234 ) {
printf("send to the port 1234 is PID %d ,process name is %s",pid(),execname())
}
}
http://blog.chinaunix.net/uid-24774106-id-3949772.html
最近我在重装了我的笔记本,OS用的是Ubuntu12.04.3,内核版本是:
- root@manu-hacks:~/software/systemtap# uname -r
3.8.0-29-generic
我安装的最新版本是3.8.0.29,但是发现按照老的方法不行了。执行:
- stap -e 'probe kernel.function("sys_open") {log("hello world") exit()}'
结果报错,报错信息是
ERROR:Build-id mismatch 云云。
不愿意听我罗嗦的,直接跳转到正确的方法
错误的尝试
我最初以为是因为systemtap版本太低,然后源代码装了systemtap 2.0/2.1/2.3的版本,结果还是不行。后来我怀疑是不是因为我kernel升过级,重新安装还是不行。在后来,我看到了Brenden's blog中有一文章叫Using SystemTap提到了这个问题,给出了Solution,无奈他的方法是老黄历了,不能解决问题,这个bug,SystemTap早就修过了.
他的解决方法是:在runtime/sym.c中将注释行替换成下面的一行,事实上,这个bug ,systemtap早就已经fix掉了。
我们看下当前的源代码:
接下来搜到了这篇文章:
SystemTap初体验,这片文章把打印出Build-id dismatch那部分的检查代码给修改了,跳过了检查build-id。
代码还是在runtime/sym.c下,把theory!= practice这个条件注释掉。
表面上看,结果是对的,但是执行真正的内核探察,就会发现会报错。因为systemtap报错是有原因的。他表明了内核符号表和运行的内核不匹配,你跳过检查,不过是掩耳盗铃的勾当。
一线曙光
我痛苦我彷徨我纠结的时候,我看到了这个帖子: systemtap reports error 'Build-id mismatch',下面有个回复提供了 脚本,这个脚本执行的结果我指明了方向。为了不让这个给了我巨大帮助的脚本湮没在历史的长河之中,为了表示我对作者的无限感激,我把它全文copy下来:
执行结果如下:
记忆力好的筒子可能会记得,我前面提到,我的内核版本是:
尼玛,我的内核版本明明是
3
.
8
.
0
-
29
.
42~precise1,可是uname -r告诉我的是
3
.
8
.
0
-
29
-
generic,而我上篇博客提到的get-dbg,错误的下载了debuginfo。
正确的方法
1 寻找到正确的内核版本,执行这个,看到我们的版本信息是
2
去
http://ddebs.ubuntu.com/pool/main/l/linux-lts-raring/
路径下找到你的debug info。下载之
3 安装之
如果你和我一样苦逼,装错了,请先执行dpkg -r 错误的版本。 如果你记不清楚错误的名字,请执行dpkg --list |grep linux-image.
如果你不是普通青年,你是文艺青年,你也可以自己下载source code,自己编出内核符号表。参考下面的步骤,来源在: Linux系统分析工具续-SystemTap和火焰图(Flame Graph),或者自行搜索 How do I build a debuginfo kernel if one isn't available?
最后,我不是文艺青年,我只是一个想顺顺利利装上systemtap的苦逼青年。泪流满面啊。
不愿意听我罗嗦的,直接跳转到正确的方法
错误的尝试
我最初以为是因为systemtap版本太低,然后源代码装了systemtap 2.0/2.1/2.3的版本,结果还是不行。后来我怀疑是不是因为我kernel升过级,重新安装还是不行。在后来,我看到了Brenden's blog中有一文章叫Using SystemTap提到了这个问题,给出了Solution,无奈他的方法是老黄历了,不能解决问题,这个bug,SystemTap早就修过了.
他的解决方法是:在runtime/sym.c中将注释行替换成下面的一行,事实上,这个bug ,systemtap早就已经fix掉了。
- if (!strcmp(m->name, "kernel")) {
- /* notes_addr = m->build_id_offset; REPLACE THIS LINE BY THE NEXT ONE */
- notes_addr = _stp_module_relocate("kernel", "_stext", m->build_id_offset);
- base_addr = _stp_module_relocate("kernel", "_stext", 0);
- } else {
- /* notes end address */
- if (!strcmp(m->name, "kernel")) {
- notes_addr = _stp_kmodule_relocate("kernel",
- "_stext", m->build_id_offset);
- base_addr = _stp_kmodule_relocate("kernel",
- "_stext", 0);
代码还是在runtime/sym.c下,把theory!= practice这个条件注释掉。
- if (rc /*|| (theory != practice*)*/) {
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
- _stp_error ("Build-id mismatch [man error::buildid]: \"%s\" byte %d (0x%02x vs 0x%02x) address %#lx rc %d\n",
- m->path, j, theory, practice, notes_addr, rc);
- return 1
一线曙光
我痛苦我彷徨我纠结的时候,我看到了这个帖子: systemtap reports error 'Build-id mismatch',下面有个回复提供了 脚本,这个脚本执行的结果我指明了方向。为了不让这个给了我巨大帮助的脚本湮没在历史的长河之中,为了表示我对作者的无限感激,我把它全文copy下来:
- #!/bin/bash
-
- distro="$(lsb_release --id --short)"
- if [ "$distro" != "Debian" -a "$distro" != "Ubuntu" ]; then
- echo Unsupported distro $distro
- exit 1
- fi
-
- # 2.6.32-5-amd64
- # 2.6.32-37-generic
- abiname="$(cut -d " " -f 3 /proc/version)"
-
- # 2.6.32
- baseversion="$(echo "$abiname" | cut -d "-" -f 1)"
-
- case "$distro" in
- Debian) # 2.6.32-39
- if uname -v | grep -q Debian; then
- version=$(uname -v | cut -d " " -f 4)
- else
- version="$(cut -d " " -f 5 /proc/version | cut -d ")" -f 1)"
- fi
- ;;
- Ubuntu)
- # 2.6.32-37.81
- version="$(cut -d " " -f 2 /proc/version_signature | cut -d "-" -f 1-2)"
- ;;
- esac
-
-
- (
- echo make >= 0
- echo linux-image-$abiname = $version
- echo linux-headers-$abiname = $version
- echo linux-kbuild-$baseversion >= $version
- case "$distro" in
- Debian) echo linux-image-$abiname-dbg = $version
- ;;
- Ubuntu) echo linux-image-$abiname-dbgsym = $version
- ;;
- esac
- ) | while read package relation requiredversion; do
- installedversion="$(dpkg-query -W "$package" 2> /dev/null | cut -f 2)"
- if [ "$installedversion" = "" ]; then
- availableversion="$(apt-cache show $package 2> /dev/null | grep ^Version: | cut -d " " -f 2)"
- if [ "$availableversion" = "" ]; then
- echo "You need package $package but it does not seem to be available"
- if [ "$distro" = "Ubuntu" -a "$(echo $package | grep dbgsym$)" ]; then
- echo " Ubuntu -dbgsym packages are typically in a separate repository"
- echo " Follow https://wiki.edubuntu.org/DebuggingProgramCrash to add this repository"
- elif [ "$distro" = "Debian" -a "$(echo $package | grep dbg$)" ]; then
- echo " Debian does not have -dbg packages for all kernels. Consider switching to a kernel that has one."
- fi
- else
- echo "Please install $package"
- fi
- elif ! dpkg --compare-versions $installedversion $relation $requiredversion; then
- echo "Package $package version $installedversion does not match version of currently running kernel: $requiredversion"
- echo " Consider apt-get upgrade && reboot"
- fi
- done
-
- user="$(id --user --name)"
- if [ "$user" != "root" ]; then
- groups="$(id --groups --name)"
- for i in stapusr stapdev; do
- if [ "$(echo $groups | grep $i)" = "" ]; then
- echo "Be root or adduser $user $i"
- fi
- done
- fi
- Package linux-image-3.8.0-29-generic-dbgsym version 3.8.0-29.42 does not match version of currently running kernel: 3.8.0-29.42~precise1
- root@manu-hacks:~/software/systemtap# uname -r
- 3.8.0-29-generic
正确的方法
1 寻找到正确的内核版本,执行这个,看到我们的版本信息是
- root@manu-hacks:~/software/systemtap# cat /proc/version_signature
- Ubuntu 3.8.0-29.42~precise1-generic 3.8.13.5
- wget http://ddebs.ubuntu.com/pool/main/l/linux-lts-raring/linux-image-3.8.0-29-generic-dbgsym_3.8.0-29.42~precise1_i386.ddeb
- dpkg -i linux-image-3.8.0-29-generic-dbgsym_3.8.0-29.42~precise1_i386.ddeb
如果你不是普通青年,你是文艺青年,你也可以自己下载source code,自己编出内核符号表。参考下面的步骤,来源在: Linux系统分析工具续-SystemTap和火焰图(Flame Graph),或者自行搜索 How do I build a debuginfo kernel if one isn't available?
- $ cd $HOME
- $ sudo apt-get install dpkg-dev debhelper gawk
- $ mkdir tmp
- $ cd tmp
- $ sudo apt-get build-dep --no-install-recommends linux-image-$(uname -r)
- $ apt-get source linux-image-$(uname -r)
- $ cd linux-2.6.31 (this is currently the kernel version of 9.10)
- $ fakeroot debian/rules clean
- $ AUTOBUILD=1 fakeroot debian/rules binary-generic skipdbg=false
- $ sudo dpkg -i ../linux-image-debug-2.6.31-19-generic_2.6.31-19.56_amd64.ddeb
更多推荐
已为社区贡献1条内容
所有评论(0)