linux 内核开启调试选项

news2024/11/25 20:32:57

前言

嵌入式 linux 经常要编译 linux 内核,默认情况下编译出的内核镜像是不带调试信息的,这样,当内核 crash 打印 PC 指针和堆栈信息时,我们需要反汇编来确认出错位置,不直观。
如果内核开启了调试选项,我们只需要一个 addr2line 命令,就可以将 PC 指针定位到 C 程序的哪个文件的哪一行,非常快捷高效。
下面我们就来介绍下,如何开启内核调试选项。

-g

gcc 编译应用程序时,使用 -g 选项编译出带有调试信息的可执行程序。编译内核也是同样的道理。所以,我们先在顶层 Makefile 中搜索 -g 选项,下面是 linux-4.1.15 例子

ifdef CONFIG_DEBUG_INFO
ifdef CONFIG_DEBUG_INFO_SPLIT
KBUILD_CFLAGS   += $(call cc-option, -gsplit-dwarf, -g)
else
KBUILD_CFLAGS	+= -g
endif
KBUILD_AFLAGS	+= -Wa,-gdwarf-2
endif
ifdef CONFIG_DEBUG_INFO_DWARF4
KBUILD_CFLAGS	+= $(call cc-option, -gdwarf-4,)
endif

要想使能 -g 选项,就要使能 CONFIG_DEBUG_INFO 编译选项。
make menuconfig,搜索 CONFIG_DEBUG_INFO

 .config - Linux/arm 4.1.15 Kernel Configuration
 → Search (CONFIG_DEBUG_INFO) ──────────────────────────────────────────────────────────
  ┌───────────────────────────────── Search Results ─────────────────────────────────┐
  │ Symbol: DEBUG_INFO [=n]                                                          │  
  │ Type  : boolean                                                                  │  
  │ Prompt: Compile the kernel with debug info                                       │  
  │   Location:                                                                      │  
  │     -> Kernel hacking                                                            │  
  │ (1)   -> Compile-time checks and compiler options                                │  
  │   Defined at lib/Kconfig.debug:120                                               │  
  │   Depends on: DEBUG_KERNEL [=y] && !COMPILE_TEST [=n]                            │  
  │                                                                                  │  
  │                                                                                  │  
  │ Symbol: DEBUG_INFO_DWARF4 [=n]                                                   │  
  │ Type  : boolean                                                                  │  
  │ Prompt: Generate dwarf4 debuginfo                                                │  
  │   Location:                                                                      │  
  │     -> Kernel hacking                                                            │  
  │       -> Compile-time checks and compiler options                                │  
  │ (2)     -> Compile the kernel with debug info (DEBUG_INFO [=y])                  │  
  │   Defined at lib/Kconfig.debug:161                                               │  
  │   Depends on: DEBUG_INFO [=y]                                                    │  
  │                                                                                  │  
  │                                                                                  │  
  │ Symbol: DEBUG_INFO_REDUCED [=n]                                                  │  
  │ Type  : boolean                                                                  │  
  ├──────────────────────────────────────────────────────────────────────────( 51%)──┤  
  │                                     < Exit >                                     │  
  └──────────────────────────────────────────────────────────────────────────────────┘  

vim .config

3244 # CONFIG_DEBUG_INFO is not set

修改为

3244 CONFIG_DEBUG_INFO=y

检查

 .config - Linux/arm 4.1.15 Kernel Configuration
 → Search (CONFIG_DEBUG_INFO) ──────────────────────────────────────────────────────────
  ┌───────────────────────────────── Search Results ─────────────────────────────────┐
  │ Symbol: DEBUG_INFO [=y]                                                          │  
  │ Type  : boolean                                                                  │  
  │ Prompt: Compile the kernel with debug info                                       │  
  │   Location:                                                                      │  
  │     -> Kernel hacking                                                            │  
  │ (1)   -> Compile-time checks and compiler options                                │  
  │   Defined at lib/Kconfig.debug:120                                               │  
  │   Depends on: DEBUG_KERNEL [=y] && !COMPILE_TEST [=n]                            │  
  │                                                                                  │  
  │                                                                                  │  
  │ Symbol: DEBUG_INFO_DWARF4 [=n]                                                   │  
  │ Type  : boolean                                                                  │  
  │ Prompt: Generate dwarf4 debuginfo                                                │  
  │   Location:                                                                      │  
  │     -> Kernel hacking                                                            │  
  │       -> Compile-time checks and compiler options                                │  
  │ (2)     -> Compile the kernel with debug info (DEBUG_INFO [=y])                  │  
  │   Defined at lib/Kconfig.debug:161                                               │  
  │   Depends on: DEBUG_INFO [=y]                                                    │  
  │                                                                                  │  
  │                                                                                  │  
  │ Symbol: DEBUG_INFO_REDUCED [=n]                                                  │  
  │ Type  : boolean                                                                  │  
  ├──────────────────────────────────────────────────────────────────────────( 51%)──┤  
  │                                     < Exit >                                     │  
  └──────────────────────────────────────────────────────────────────────────────────┘  



看到 Symbol: DEBUG_INFO [=y] ,这样 -g 编译选项就开启了。
重新编译内核,然后检查镜像文件

$ file vmlinux
vmlinux: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=bfb6aefe3b6955df44222bfefc9ee5b4955f9c81, with debug_info, not stripped

看到 with debug_info,这样内核镜像就带有调试信息了。后面使用 openOCD 进行硬件调试,或者根据 crash 信息定位出错代码位置都是很方便的。

实例

如下图,在 do_mount_root 函数中添加一个调试 BUG。
在这里插入图片描述

板子运行后报错如下

ALSA device list:
  No soundcards found.
------------[ cut here ]------------
Kernel BUG at 809c70a8 [verbose debug info unavailable]
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.1.15 #95
Hardware name: Freescale i.MX6 Ultralite (Device Tree)
task: 88048000 ti: 8804c000 task.ti: 8804c000
PC is at do_mount_root.part.3+0x38/0x44
LR is at mntput_no_expire+0x40/0x1ec
pc : [<809c70a8>]    lr : [<80115138>]    psr: 60000113
sp : 8804df00  ip : 00000000  fp : 8804df04
r10: 8086900c  r9 : 80869154  r8 : 000003e8
r7 : 80a90024  r6 : 00000006  r5 : 80a33888  r4 : 00000005
r3 : 0000000f  r2 : 80a90024  r1 : 0b10a000  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 8000406a  DAC: 00000015
Process swapper/0 (pid: 1, stack limit = 0x8804c210)
Stack: (0x8804df00 to 0x8804e000)
df00: 8804df3c 809c74d4 80a1bf6c 801067e0 80a1c474 80a1bf6c 88030040 80a1aac4
df20: 80a90024 80a90000 80a1aaa0 8094d744 80a90000 809c6620 8804df5c 809c76c4
df40: 80a1aaa0 8094d744 00000008 000000d2 80a90000 80a1aaa0 8804df9c 809c6ebc
df60: 00000007 00000007 809c6620 00000000 8804df7c 00000008 8804df9c 00000000
df80: 806d63c4 00000000 00000000 00000000 00000000 00000000 8804dfac 806d63d0
dfa0: 00000000 806d63c4 00000000 80010408 00000000 00000000 00000000 00000000
dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 5fedd77f e7ffbaae
[<809c70a8>] (do_mount_root.part.3) from [<809c74d4>] (mount_root+0x74/0x100)
[<809c74d4>] (mount_root) from [<809c76c4>] (prepare_namespace+0x164/0x1c8)
[<809c76c4>] (prepare_namespace) from [<809c6ebc>] (kernel_init_freeable+0x18c/0x1dc)
[<809c6ebc>] (kernel_init_freeable) from [<806d63d0>] (kernel_init+0xc/0xec)
[<806d63d0>] (kernel_init) from [<80010408>] (ret_from_fork+0x14/0x2c)
Code: e5933020 e593305c e5933008 e582300c (e7f001f2)
---[ end trace 48ec6f9402ae51bf ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

random: nonblocking pool is initialized

开门见山地就提示我们 Kernel BUG at 809c70a8,那我们就用 addr2line 来看看到底是哪行代码

$ addr2line -f -e vmlinux 0x809c70a8
do_mount_root
/home/liyongjun/project/board/IMX6ULL/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/init/do_mounts.c:373

do_mounts.c 文件的第 373 行
在这里插入图片描述
一下就定位到了出错位置,这就是内核开启调试选项的好处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/525680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

控制系统中的闭环带宽

控制系统中的闭环带宽是指反馈控制系统中控制器输出与被控对象输入之间的频率范围。具体来说&#xff0c;闭环带宽是在稳定性和响应速度之间做出的折衷&#xff0c;越高的闭环带宽通常意味着更快的响应速度&#xff0c;但也可能导致系统变得不稳定。 在实际应用中&#xff0c;…

HTML <base> 标签

实例 <head> <base href="http://www.w3school.com.cn/i/" /> <base target="_blank" /> </head><body> <img src="eg_smile.gif" /> <a href="http://www.w3school.com.cn">W3School<…

JAVA常用ApI - Object和Objects

文章目录 目录 文章目录 前言 一 .Object是什么&#xff1f; 二 .Object的常用方法 1.tostring 1.1 返回值 1.2 重写toString方法 3.clone(克隆) 1.克隆接口 三.Objects 总结 前言 大家好,我是最爱吃兽奶,今天给大家讲一下java中的object和object的工具类objects 那…

泰裤辣,可以利用AI测测Vue知识的掌握程度。

以下是一些常见的Vue面试题&#xff1a; 可以先试着回答&#xff0c;以下是参考答案。 1. 什么是Vue&#xff0c;它的优点是什么&#xff1f; Vue是一套用于构建用户界面的渐进式JavaScript框架&#xff0c;它以简洁的API和响应式数据绑定的特性来大大简化了前端开发过程。Vue…

Linux基本指令和操作(3)

目录 一. date指令 -- 显示时间 二. cal指令 -- 日历打印指令 三. find指令 -- 查找文件 四. grep指令 -- 行过滤指令 五. zip/unzip指令 -- 压缩和解压缩 六. tar指令 -- 解压/打包 或 查看压缩包内文件 七. bc指令 -- 计算器 八. uname指令 -- 获取电脑和操作系统相关…

webserver|4.23-4.24 TCP状态转换、半关闭、端口复用

4.23 TCP状态转换 四次挥手&#xff1a; 另一种状态图&#xff1a; 红色实线&#xff1a;客户端 绿色虚线&#xff1a;服务端状态转变 4.24 半关闭、端口复用 半关闭 基本就是一边closed&#xff0c;另一边还没有closed 一边一旦closed之后就不能再向另一方传数据&#xff08;A…

异常检测专栏(三)传统的异常检测算法——上

前言 在上一篇推文中&#xff0c;我们简要介绍了异常检测常用的几种数据集如ImageNet、CIFAR10/CIFAR100、MNIST等。接下来&#xff0c;我们将基于传统的异常检测算法分为上、下两部分&#xff0c;逐一介绍不同类别的方法。 本教程禁止转载。同时&#xff0c;本教程来自知识星球…

matlab将RGB图像在HSI空间去噪

思路与代码 RGB 转换为 HSI 的计算步骤如下&#xff1a; 首先归一化三通道值 &#xff1a; r R R G B r \frac{R}{RGB} rRGBR​ g G R G B g \frac{G}{RGB} gRGBG​ b B R G B b \frac{B}{RGB} bRGBB​ 接下来&#xff0c;计算 HSI 图像的亮度 I I I&#xf…

(转载)从0开始学matlab(第3天)—子数组

你可以选择和使用一个 MATLAB 函数的子集&#xff0c;好像他们是独立的数组一样。在数组名后面加括号&#xff0c;括号里面是所有要选择的元素的下标&#xff0c;这样就能选择这个函数的子集了。例如&#xff0c;假设定义了一个数组 arr1 如下 arr1[1.1 -2.2 3.3 -4.4 5.5] 那…

yolov5 实例分割 jason标注格式转换 训练自己的数据集

目录 一、coco128-seg数据集分析 1、配置文件 coco128-seg.yaml 2、coco128-seg数据集 二、自己用anylabeling标注获得的json文件 三、json文件转coco128-seg格式 四、实例分割训练 1、修改数据配置文件 coco128-seg.yaml 2、训练 一、coco128-seg数据集分析 这个博客中有…

5。STM32裸机开发(3)

嵌入式软件开发学习过程记录&#xff0c;本部分结合本人的学习经验撰写&#xff0c;系统描述各类基础例程的程序撰写逻辑。构建裸机开发的思维&#xff0c;为RTOS做铺垫&#xff08;本部分基于库函数版实现&#xff09;&#xff0c;如有不足之处&#xff0c;敬请批评指正。 &…

【探索SpringCloud】服务发现

前言 今天&#xff0c;我们来聊聊SpringCloud服务发现。主要有如下几个议题&#xff1a; 一、服务发现的概念与方案&#xff1b;二、SpringCloud是如何与各个服务注册厂商进行集成的。 服务发现 在微服务架构中&#xff0c;我们不可避免的需要通过服务间的调用来完成系统功能…

Fourier分析入门——第1章——数学预备知识

第 1 章 学习Fourier分析的数学预备知识 目录 第 1 章 学习Fourier分析的数学预备知识 1.1 引言 1.2 几何和代数的一些相关概念的回顾 1.2.1 标量运算(scalar arithmetic) 1.2.2 向量运算(vector arithmetic) 1.2.3 向量乘法(vector multiplication) 1.2.4 向量长度 …

设计模式(java)-观察者模式

1. 简介 观察者模式&#xff0c;行为型设计模式。观察者模式在实际项目实践中&#xff0c;是一种使用较频繁的设计模式&#xff0c;它主要解决的是信息同步的问题&#xff0c;当多个对象需要从同一个主题中得到自身所需要的信息或状态&#xff0c;并通过这些信息或状态做出相应…

以太网外设ETH

1. 概述 近几年&#xff0c;项目需要&#xff0c;在多款单片机上使用了以太网外设。 本文为阶段知识整理&#xff0c;查缺补漏&#xff0c;方便以后再次遇到相关任务时&#xff0c;可以游刃有余的完成工作。 1.1 修改时间 2023年5月6日创建本文。包含STM32的ETH外设。2023年…

利用CNN对车牌进行智能识别(python代码,解压缩后直接运行)

1.代码流程 该段代码主要利用卷积神经网络&#xff08;CNN&#xff09;来识别车牌。下面是代码的主要流程&#xff1a; 导入所需的库和模块&#xff0c;包括matplotlib、numpy、cv2、tensorflow等。 加载用于检测车牌的级联分类器&#xff08;cascade classifier&#xff09;…

可见光遥感目标检测(一)任务概要介绍

前言 本篇开始对遥感图像的目标检测进行介绍&#xff0c;介绍了其目标前景、数据集以及评价指标。 本教程禁止转载。同时&#xff0c;本教程来自知识星球【CV技术指南】更多技术教程&#xff0c;可加入星球学习。 Transformer、目标检测、语义分割交流群 欢迎关注公众号CV技…

机器学习13(正则化)

文章目录 简介正则化经验风险和结构风险过拟合正则化建模策略 逻辑回归逻辑回归评估器 练习评估器训练与过拟合实验评估器的手动调参 简介 这一节详细探讨关于正则化的相关内容&#xff0c;并就 sklearn 中逻辑回归&#xff08;评估器&#xff09;的参数进行详细解释由于 skle…

javaweb项目实战之myBlog

项目简介 技术栈&#xff1a; Java Mysql Html Ajax Css JS Json 项目说明 &#xff1a;项目使用maven创建&#xff0c;使用MVC架构模式 表示层&#xff1a;通俗讲就是展现给用户的界面和控制器层Servlet&#xff0c;接受请求、封装数据、调用业务 逻辑层&#xff0c;响…

libevent高并发网络编程 - 05_libevent实现http客户端

文章目录 1 http客户端相关的APIevhttp_uri_parse()evhttp_uri_get_scheme()evhttp_uri_get_port()evhttp_uri_get_host()evhttp_uri_get_path()evhttp_uri_get_query()evhttp_connection_base_bufferevent_new()evhttp_request_new()evhttp_make_request()evhttp_request_get_…