Linux 5.0 forkdumpcrashlabonarm 64
=========================================================================================
愚蠢的大叔已经录制了视频课程节目,这是世界上唯一一个介绍如何解决产品开发和服务器故障的视频课程。
视频课程全程5小时高清、140多页ppt、8大实验、基于x86_64的Centos 7.6和arm64,提供所有实验素材和环境。
全面介绍kdump crash在恐慌黑屏中的实战应用。 所有案例都来源于在线云服务器和嵌入式产品开发的实际案例。
挑战恐慌的专题片中的8个恐慌案例:
lab1 )基于简单空指针的panic
lab2 :访问被删除的list head链表
lab3 )基于稍微复杂的空指针的panic
lab4 )实际驱动引起的死机
lab5 )实际驱动引起的死锁会导致系统死机
lab6:如何找到函数调用参数在堆栈中的地址以获取具体值
lab7)分析复杂的在线死锁引起的死机的黑色画面的例子
lab8:手动恢复函数调用堆栈backtrack(arm64 ) )。
购买恐慌黑屏专题课程: https://shop115683645.taobao.com/
安装方法:
=========================================================================================
本实验代码不支持“O0”编译。 如果需要“O0”编译的Linux 5.0内核源代码和实验环境,请联系傻kddjm,wechat:runninglinuxkernel
本实验构建在安装了Ubuntu 18.04.2版的x86_64台式机或PC上。 如果要使用其他版本的ubuntu或分发,请在遇到问题时自行解决。 需要特别注意的是qemu的版本不能太旧。
1 .首先,在Ubuntu Linux 18.04上安装以下工具:
$ sudo apt-getinstallqemulibncurses5- dev gcc-a arch 64-Linux-GNU build-essentialgitbisonflexlibssl-dev
rootfs_Debian.tar.xz文件位于runninglinuxkernel目录下。 这是一个基于ARM64版本debian系统的根文件系统。 但是,这个根文件系统还是半成品,必须基于编译的内核安装内核镜像和内核模块。 整个过程很复杂:
*编译内核
*编译内核模块
*安装内核模块
*安装内核标头
*安装已编译的内核模块必须依赖于文件
创建ext4根文件系统
这个过程很繁琐,作者编写了用于简化上述过程的脚本。
请注意,由于该脚本使用dd命令生成8GB大小的镜像文件,因此主机系统必须至少有10GB的可用磁盘空间。 如果读者需要为更大的根文件系统创建镜像,则可以修改名为run_debian_arm64.sh的脚本文件。
$ cd runninglinuxkernel-5.0
$./run _ debian _ arm 64.sh build _ kernel
执行上述脚本需要几十分钟,取决于主机的计算能力。
编译rootfs文件系统
$ sudo./run _ debian _ arm 64.sh build _ rootfs
4 .开车。
$ ./run_debian_arm64.sh run
登录到Debian系统:
*用户名:超级用户或别墅
*密码: 123
5 .在线安装软件包
qmu虚拟机可以使用VirtIO-NET技术生成虚拟网卡,并使用NAT网络桥接技术和主机进行网络共享。 首先使用ifconfig命令检查网络配置。
root@benshushu:~# ifconfig
将生成名为enp0s1的NIC设备,并看到分配的IP地址为10.0.2.15。
使用apt update命令更新Debian系统的软件仓库。
$ apt update
如果更新失败,则系统时间可能已过时。 可以使用date命令设置日期。
root @ Ben shushu :~# date-s 2019-04-25 #假设最新日期为2019年4月25日
thuapr2500:00:00utc2019
使用apt install命令安装软件包。 例如,可以在线安装gcc。
root @ Ben shushu :~# aptinstallgcc
6 .在主机和QEMU虚拟机之间共享文件。
主机和QEMU虚拟机可以通过NET_9P技术共享文件,其中QEMU虚拟机的Linux内核需要支持NET_9P的内核模块。
本实验平台已与主机
QEMU虚拟机的共享文件,可以通过如下简单方法来测试。复制一个文件到runninglinuxkernel-5.0/kmodules目录下面。比如拷贝vmlinux。
$cp vmlinux runninglinuxkernel-5.0/kmodules
启动QEMU虚拟机之后,首先检查一下/mnt目录是否有vmlinux文件。
/ # cd /mnt/
/mnt # ls
01_oops vmlinux
/mnt #
我们在后续的实验中会经常利用这个特性,比如把编译好的内核模块或者内核模块源代码放入QEMU虚拟机。
7. 在QEMU虚拟机上本地编译内核模块。
在QEMU虚拟机中安装必要的软件包。
root@benshushu: # apt install build-essential
编译内核模块。
root@benshushu:/mnt/01_oops# make
8. 使用systemctl status kdump-tools命令来查看kdump服务是否正常工作。
编译一个简单的死机例子。加载模块的时候会触发重启,进入捕获内核,比如加载刚才编译的模块:
root@benshushu:/mnt/01_oops# insmod oops.ko
[ 1016.544189] oops: loading out-of-tree module taints kernel.
[ 1016.562363] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050
[ 1016.562821] Mem abort info:
[ 1016.562993] ESR = 0x96000004
[ 1016.563202] Exception class = DABT (current EL), IL = 32 bits
[ 1016.563480] SET = 0, FnV = 0
[ 1016.563612] EA = 0, S1PTW = 0
[ 1016.563776] Data abort info:
[ 1016.563937] ISV = 0, ISS = 0x00000004
[ 1016.564412] CM = 0, WnR = 0
[ 1016.564823] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000c742141d
[ 1016.565216] [0000000000000050] pgd=0000000000000000
[ 1016.565840] Internal error: Oops: 96000004 [#1] SMP
[ 1016.566239] Modules linked in: oops(OE+) aes_ce_blk(E) crypto_simd(E) cryptd(E) aes_ce_cipher(E) ghash_ce(E) gf128mul(E) aes_arm64(E) sha2_ce(E) evdev(E) sha256_arm64(E) sha1_ce(E) cfg80211(E) rfkill(E) 8021q(E) garp(E) mrp(E) stp(E) llc(E) gpio_keys(E) virtio_net(E) net_failover(E) failover(E) 9p(E) fscache(E) ip_tables(E) x_tables(E) autofs4(E)
[ 1016.568152] CPU: 3 PID: 1659 Comm: insmod Kdump: loaded Tainted: G OE 5.0.0-rlk+ #1
[ 1016.568853] Hardware name: linux,dummy-virt (DT)
[ 1016.569236] pstate: 80000005 (Nzcv daif -PAN -UAO)
[ 1016.569995] pc : create_oops+0x20/0x4c [oops]
[ 1016.570267] lr : my_oops_init+0xa0/0x1000 [oops]
[ 1016.570469] sp : ffff000012873b20
[ 1016.570640] x29: ffff000012873b20 x28: ffff0000113fb090
[ 1016.571028] x27: ffff000008cf81d0 x26: ffff000008cf8180
[ 1016.571305] x25: ffff000010b66988 x24: ffff0000113fb000
[ 1016.571564] x23: ffff000008cf8018 x22: ffff800027249a80
[ 1016.571849] x21: 0000000000000000 x20: ffff000008c02000
[ 1016.572260] x19: ffff0000113cd000 x18: ffffffffffffffff
[ 1016.572601] x17: 0000000000000000 x16: 0000000000000000
[ 1016.572885] x15: ffff0000113cd708 x14: ffff8000234f791c
[ 1016.573152] x13: 0000000000000040 x12: 0000000000000228
[ 1016.573506] x11: 0000000000000000 x10: 0000000000000000
[ 1016.573788] x9 : 0000000000000000 x8 : ffff8000291cf600
[ 1016.574027] x7 : ffff80002a803b00 x6 : ffff000012873b89
[ 1016.574264] x5 : 0000000000000cfd x4 : ffff80002fde1b00
[ 1016.574503] x3 : 0000000000000000 x2 : ffff000008c020a0
[ 1016.574746] x1 : ffff000012873b84 x0 : 0000000000000000
[ 1016.575060] Process insmod (pid: 1659, stack limit = 0x0000000022ed716c)
[ 1016.575510] Call trace:
[ 1016.575789] create_oops+0x20/0x4c [oops]
[ 1016.576020] my_oops_init+0xa0/0x1000 [oops]
[ 1016.576741] do_one_initcall+0x54/0x1f0
[ 1016.577009] do_init_module+0x64/0x1d8
[ 1016.577182] load_module+0x1db8/0x1f00
[ 1016.577347] __se_sys_finit_module+0xf0/0x100
[ 1016.577533] __arm64_sys_finit_module+0x24/0x30
[ 1016.577739] el0_svc_common+0x78/0x120
[ 1016.577936] el0_svc_handler+0x38/0x78
[ 1016.578125] el0_svc+0x8/0xc
[ 1016.578447] Code: f9000be1 aa0203e0 d503201f f9400fe0 (f9402800)
[ 1016.579516] SMP: stopping secondary CPUs
[ 1016.581326] Starting crashdump kernel...
[ 1016.581787] Bye!
系统重启到capture内核,然后启动kdump服务来进行内核转存。
[ 32.574743] kdump-tools[256]: Starting kdump-tools: running makedumpfile -c -d 31 /proc/vmcore /var/crash/201906201406/dump-incomplete.
Copying data : [100.0 %] / eta: 0s
转存完成之后,再一次重启,启动到正常的内核。
转存好的文件在:/var/crash/目录
9.在QEMU虚拟机中,启动crash工具进行分析。
进入/var/crash/目录。转存的目录是以日期来命名,这一点和Centos系统略有不同。使用crash命令来加载内核转存文件。
需要在另外一个终端里拷贝vmlinux文件到runninglinuxkernel-5.0/kmodules.
root@benshushu:/var/crash# ls
201904221429 kexec_cmd
root@benshushu:/var/crash#
root@benshushu:/var/crash/201904221429# crash dump.201904221429 /mnt/vmlinux
KERNEL: /mnt/vmlinux
DUMPFILE: dump.201904221429 [PARTIAL DUMP]
CPUS: 4
DATE: Mon Apr 22 14:28:49 2019
UPTIME: 00:00:13
LOAD AVERAGE: 0.47, 0.31, 0.13
TASKS: 87
NODENAME: benshushu
RELEASE: 5.0.0+
VERSION: #1 SMP Mon Apr 22 05:40:30 CST 2019
MACHINE: aarch64 (unknown Mhz)
MEMORY: 2 GB
PANIC: "Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050"
PID: 1243
COMMAND: "insmod"
TASK: ffff800052d0c600 [THREAD_INFO: ffff800052d0c600]
CPU: 0
STATE: TASK_RUNNING (PANIC)
crash>