Skip to main content
 首页 » 操作系统

Linux内核调试汇总

2022年07月19日45落叶无声

1.控制台优先级配置
cat /proc/sys/kernel/printk
6 4 1 7
6是控制台的优先级,打印信息的优先级要比它高才能打印出。
4是默认的优先级
cat /var/log/messages 不管你的打印信息有没有打印,这个文件中都有记录

修改日志方法:https://blog.csdn.net/tonywgx/article/details/17504001

# cat /proc/sys/kernel/printk
7 4 1 7

该文件有四个数字值,它们根据日志记录消息的重要性,定义将其发送到何处。关于不同日志级别的更多信息,请查阅syslog(2)联机帮助。
上面显示的4个数据分别对应:
控制台日志级别:优先级高于该值的消息将被打印至控制台
默认的消息日志级别:将用该优先级来打印没有优先级的消息
最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)
默认的控制台日志级别:控制台日志级别的缺省值

#define KERN_EMERG KERN_SOH "0" /* system is unusable */
#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
#define KERN_CRIT KERN_SOH "2" /* critical conditions */
#define KERN_ERR KERN_SOH "3" /* error conditions */
#define KERN_WARNING KERN_SOH "4" /* warning conditions */
#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
#define KERN_INFO KERN_SOH "6" /* informational */
#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */

echo 7 4 1 7 > /proc/sys/kernel/printk

在console_printk中静态指定的
int console_printk[4] = {
CONSOLE_LOGLEVEL_DEFAULT, /*7: console_loglevel */ 将其改为8,KERN_DEBUG等级的也可以打印出来!
MESSAGE_LOGLEVEL_DEFAULT, /*4: default_message_loglevel */
CONSOLE_LOGLEVEL_MIN, /*1: minimum_console_loglevel */
CONSOLE_LOGLEVEL_DEFAULT, /*7: default_console_loglevel */
};
将其改为6 3 1 6,然后再/proc/sys/kernel/printk中的就是6 3 1 6了

2. 反汇编命令
arm-linuc-objdump –D –S holle.ko –>log.txt  可用于debug oops

3. printk/trace_printk

printk()函数学习笔记: https://www.cnblogs.com/hellokitty2/p/9867168.html

4. dynamic debug

dynamic_debug和pr_debug()打印_高通平台: https://www.cnblogs.com/hellokitty2/p/14746489.html

5. dump_stack() 打印栈回溯

6. 使用 __builtin_return_address 打印调用函数名

gcc中__builtin_return_address学习与使用: https://www.cnblogs.com/hellokitty2/p/15887006.html

7. native获取内核版本

# cat /proc/version 
Linux version 5.10.66-android12-9-g95a4d258744f (build-user@build-host) (Android (7234624, based on r411283b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016265302412d708641122d2f7ee), LLD 12.0.5 (/buildbot/src/android/llvm-toolchain/out/llvm-project/lld c935d9979cf20162893024167708641d52d2f7ee)) #1 SMP PREEMPT Fri Feb 11 09:11:35 UTC 2022

信息来自 /proc/version

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <errno.h> 
 
struct kern_info { 
    int version_maj; 
    int version_min; 
    int version_sub; 
}; 
 
int get_kernel_info(char *line, struct kern_info *info) 
{ 
    int ret, maj, min, sub; 
    ret = sscanf(line, "Linux version %d.%d.%d", &maj, &min, &sub); 
    if (ret != EOF) { 
        info->version_maj = maj; 
        info->version_min = min; 
        info->version_sub = sub; 
        printf("Linux version: %d.%d.%d\n", maj, min, sub); 
        return 0; 
    } 
    return -1; 
}  
 
int main() 
{ 
    FILE *filp; 
    char *line = NULL; 
    size_t len = 0; 
    int read_size; 
    struct kern_info info; 
 
    //F_OK check exit, R_OK W_OK X_OK check permission 
    if(access("/proc/version", F_OK) != 0) { 
        printf("file not exit\n"); 
        return -1; 
    } 
    printf("file exit\n"); 
 
    filp = fopen("/proc/version", "r"); 
    if(!filp) { 
        printf("open failed, errno=%d: %s", errno, strerror(errno)); 
        return -1; 
    } 
 
    read_size = getline(&line, &len, filp); 
    if(read_size == -1) { 
        printf("read failed, errno=%d: %s", errno, strerror(errno)); 
        free(line); 
        return -1; 
    } 
    printf("read_size=%d\n", read_size); //164,将整个cat /proc/version都读取出来了 
 
    get_kernel_info(line, &info); 
 
    free(line); 
    fclose(filp); 
 
    return 0; 
}

也可以先判断line不等于null再释放。

8. sys proc文件接口命令处理参考

#include <stdio.h> 
#include <string.h> 
 
void main(int argc, char **argv) 
{ 
    char *token; 
    char *stringp = argv[1]; 
     
    while((token = strsep(&stringp, " ")) != NULL) { 
        printf("%s\n", token); 
    } 
} 
 
/* 
$ gcc strsep_test.c -o pp 
$ ./pp "11 22 33" 
11 
22 
33 
*/

本文参考链接:https://www.cnblogs.com/hellokitty2/p/9433452.html