Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >linux、kernel 使用 systemtap 分析 sys_clone 失败的原因

linux、kernel 使用 systemtap 分析 sys_clone 失败的原因

原创
作者头像
皮振伟
修改于 2017-09-25 03:05:59
修改于 2017-09-25 03:05:59
3.1K00
代码可运行
举报
文章被收录于专栏:皮振伟的专栏皮振伟的专栏
运行总次数:0
代码可运行

前言:

在《qemu的一次pthread create失败的分析》中分析了pthread失败的原因以及解决方法。修改了pidmax之后,一直没有看到现象发生,但是不能证明问题被解决了,因为当时的环境只有coredump文件,没有找到固定的复现规律。继续观察中。 坏消息是问题又复现了。 好消息是问题能复现了。

分析:

1、clone fail

作者写了脚本,批量启动大量的qemu进程。在启动很大量的qemu之后,会有部分qemu进程crash。结合之前的分析过程,作者判断,很可能是系统调用clone发生了失败。是时候使用systemtap了。 使用systemtap需要有debug symbol,如果是发行版,可以参考发行版提供的kernel symbol,参考官方的教程,可以搭建起来systemtap的使用环境。如果是个人维护的kernel,那么就需要保存对应的symbol。 作者写了下面的脚本来监控qemu进程调用sys_clone的返回值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
probe begin {
    printf("start moniting qemu clone syscall...\n")
}

probe kernel.function("sys_clone") {
    if (execname() == "qemu-system-x86") {
        printf("sys_clone : %s\n", execname())
    }
}

probe kernel.function("sys_clone").return {
    if (execname() == "qemu-system-x86") {
        printf("sys_clone_return : %s, %d\n", execname(), $return)
        if ($return < 0)
            printf("[error]sys_clone_return : %s, %d\n", execname(), $return)
    }
}

启动stap:stap -vv -g clone.stp 复现到问题的时候,抓到了返回值是11,也就是EAGAIN。那就说明,确确实实因为kernel的clone返回值是EAGAIN,glibc的pthread create失败

2、stap error

继续分析linux-4.4/kernel/fork.c, clone的核心实现部分在copy process中,发现在下面的逻辑中都可能返回:

上面的行号,就是出错的地方,那么继续写stap脚本来监控上面的各个地方:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
probe kernel.statement("*@kernel/fork.c:1648") {
    printf("[error]copy_process@1648 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1651") {
    printf("[error]copy_process@1651 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1654") {
    printf("[error]copy_process@1654 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1657") {
    printf("[error]copy_process@1657 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1659") {
    printf("[error]copy_process@1659 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1662") {
    printf("[error]copy_process@1662 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1665") {
    printf("[error]copy_process@1665 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1667") {
    printf("[error]copy_process@1667 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1669") {
    printf("[error]copy_process@1669 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1671") {
    printf("[error]copy_process@1671 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1675") {
    printf("[error]copy_process@1675 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1678") {
    printf("[error]copy_process@1678 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1683") {
    printf("[error]copy_process@1683 : %s\n", execname())
}

probe kernel.statement("*@kernel/fork.c:1686") {
    printf("[error]copy_process@1686 : %s\n", execname())
}

在使用stap执行脚本的时候,如果stap报错,需要耐心一点,比对行号已经对应的位置上是不是有语句,不然stap会报错说指定的行数不能stap。 执行后发现,是1651行开始出错的。也就是说明,跳转到bad_fork_free_pid的地方出错了。

3、cgroup check fail

可见,是cgroup检查出错了。

4、cgroup pids

linux-4.4/kernel/cgroup.c中,继续分析:

一次检查cgroup的各个资源组。需要确定具体是哪个资源,也就是出错的时候,i的数值。 继续写stap脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
probe kernel.statement("*@kernel/cgroup.c:5573") {
    if ($ret != 0) {
        printf("[error]cgroup@5573 : %s\n", execname())
        printf("       cgroup@5573 : i = %d\n", $i )
    }
}

复现后发现,出错的时候,i的值是11。 结合linux-4.4/include/linux/cgroup_subsys.h发现,11就是在检查pids的时候发生的错误

5、pids

cat /proc/PID/cgroup来查看qemu使用的cgroup。 发现是10:pids:/system.slice/libvirtd.service 继续查看:/sys/fs/cgroup/pids/system.slice/libvirtd.service/pids.max 结果是512。 qemu进程中包含多个线程,在qemu比较多的时候,就容易发生pids超过限制的问题了。 这个问题的root cause就是pids限制的问题了。

6、libvirt pids

检查libvirt3.2的代码发现,libvirt中不支持pids的配置。 centos7的kernel是3.10,在linux3.10中,还不支持pids cgroup。所以libvirt不支持也不是特别惊奇的事情了。那么就要自己想办法修改一下这个配置了。 这个问题到此分析结束。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[linux][systemtap]使用systemtap分析qemu发生crash的原因
前言: 在《[linux][pthread]qemu的一次pthread create失败的分析》中分析了pthread失败的原因以及解决方法。修改了pidmax之后,一直没有看到现象发生,但是不能证明问题被解决了,因为当时的环境只有coredump文件,没有找到固定的复现规律。继续观察中。 坏消息是问题又复现了。 好消息是问题能复现了。 分析: 1,clone fail 作者写了脚本,批量启动大量的qemu进程。在启动很大量的qemu之后,会有部分qemu进程crash。结合之前的分析过程,作者判断,
皮振伟
2018/04/09
2K0
[linux][systemtap]使用systemtap分析qemu发生crash的原因
systemtap从入门到放弃(二)
上一篇《systemtap从入门到放弃(一)》我们知道了什么是systemtap,以及如何书写简单的systemtap脚本。本篇承接上文,介绍systemtap的安装和简易场景应用,通过几个小例子掌握systemtap在内核开发调试中的简单使用。
233333
2023/01/05
1.2K0
​[linux][pthread]qemu的一次pthread create失败的分析
前言: qemu发生了crash。这种类型的问题比较少见,这里说一下这个问题的分析过程。 分析: 1,coredump 生成的coredump,一种是配置了/proc/sys/kernel/cor
皮振伟
2018/04/09
1.1K0
​[linux][pthread]qemu的一次pthread create失败的分析
systemtap从入门到放弃(一)
内核开发从业者,都知道一个代码调试"大杀器":printk !除此之外大家依据自己的习惯,还经常用一些诸如kdump这类的复杂工具。对于systemtap,有人可能熟悉有人可能没听过,本文从入门层次简介systemtap的原理和安装使用,分为两篇,本篇主要介绍原理和脚本语法。文章冗长,多处包含"劝退"功能,下面跟我一起"从入门到放弃" 吧 -_-
233333
2023/01/01
1.2K0
systemtap从入门到放弃(一)
Linux下systemtap和火焰图介绍及安装
SystemTap 是对 Linux 内核监控和跟踪的工具,详细的介绍及说明见官网。
用户8705059
2021/06/08
1.5K0
linux、pthread、qemu 的一次 pthread create 失败的分析
皮振伟
2017/08/11
2.8K0
linux、pthread、qemu 的一次 pthread create 失败的分析
Linux Clone函数
注:本文的代码仅用于功能验证,不能用于生产。本文对clone的标志的描述顺序有变,主要考虑到连贯性。
charlieroro
2021/01/20
6.8K0
使用GDB调试Linux内核
GDB(GNU Debugger)是Linux上的调试程序,可用于C/C++、Go、Rust等多种语言。GDB可以让你在被调试程序执行时看到它的”内部“情况,观察程序在特定断点上的状态,并逐行运行代码。
mazhen
2023/11/24
1.9K0
使用GDB调试Linux内核
《Linux内核分析》之分析fork函数对应的系统调用处理过程
xref: /linux-3.18.6/include/linux/sched.h
WindCoder
2018/09/20
1.1K0
《Linux内核分析》之分析fork函数对应的系统调用处理过程
Linux内核14-clone()、fork()和vfork()的区别
Linux内核用于创建进程的系统调用有3个,它们的实现分别为:fork、vfork、clone。它们的作用如下表所示:
Tupelo
2022/08/15
1.9K0
Linux Rootkit如何避开内核检测的
如果我们想注入一个Rootkit到内核,同时不想被侦测到,那么我们需要做的是精妙的隐藏,并保持低调静悄悄,这个话题我已经谈过了,诸如进程摘链,TCP链接摘链潜伏等等,详情参见:https://blog.csdn.net/dog250/article/details/105371830
Linux阅码场
2020/05/15
1.4K0
Linux大文件重定向和管道的效率对比
大家先看一下上面二个命令,假如huge_dump.sql文件很大,然后猜测一下哪种导入方式效率会更高一些?
用户6543014
2020/03/04
1.6K0
一文看懂 | fork 系统调用
Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量级进程,也叫线程,是共享资源的进程)
用户7686797
2021/10/20
2.6K0
CVE-2019-14287(Linux sudo 漏洞)分析
近日 sudo 被爆光一个漏洞,非授权的特权用户可以绕过限制获得特权。官方的修复公告请见:https://www.sudo.ws/alerts/minus_1_uid.html。
知道创宇云安全
2019/10/22
8890
CVE-2019-14287(Linux sudo 漏洞)分析
揭开服务程序“被杀”之谜
对于第一种情况,一般可以通过coredump看出。第二个种情况,也可以通过dmesg找到线索(一般是被oom killer杀掉)。但是当后两种情况出现时,往往是大家最抓瞎最手足无措的时候。
glinuxer
2020/06/05
1.7K0
[THP][redis]THP对redis的影响
前言: 前文《[linux][redis]bgsave引起的latency突刺问题分析》分析了redis-server执行bgsave因为fork引起的latency突刺问题。 而在http://antirez.com/news/84中也提到了“However this is definitely not the full story”,剩下的story则是Linux的THP对redis的影响。 分析: 1,THP vs Normal page 配置了THP策略分别是always和never,redis-server和redis-benchmark配置相同的参数,执行bgsave的latency对比:
皮振伟
2018/07/23
1.7K0
[THP][redis]THP对redis的影响
原来进程是这么创建的
大家好,我是程栩,一个专注于性能的大厂程序员,分享包括但不限于计算机体系结构、性能优化、云原生的知识。
程栩的性能优化笔记
2023/11/01
4080
原来进程是这么创建的
fork系统调用过程分析
fork函数通过系统调用创建一个与原来进程几乎完全相同的进程,一个进程调用fork函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。
De4dCr0w
2019/02/27
2.1K0
ulimit -t 设置引起进程被Kill掉
貌似限制的是CPU最大执行时间,以秒为单位。 为了验证上面的说法,我特地设计了以下的场景:我们首先运行一个死循环程序消耗CPU时间,同时把进程的最大CPU消耗时间设定在180秒,期待在这个时间点进程会被杀掉。 以下是验证过程:
EltonZheng
2021/01/26
9020
Iowait的成因、对系统影响及对策
什么是iowait? 顾名思义,就是系统因为io导致的进程wait。再深一点讲就是:这时候系统在做io,导致没有进程在干活,cpu在执行idle进程空转,所以说iowait的产生要满足两个条件,一是进
李海彬
2018/03/23
12.3K0
Iowait的成因、对系统影响及对策
推荐阅读
相关推荐
[linux][systemtap]使用systemtap分析qemu发生crash的原因
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验