Linux内核调试汇总

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再释放。

uname -r 命令也可以获取内核版本。

 

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
*/

 

posted on 2018-08-06 21:30  Hello-World3  阅读(332)  评论(0编辑  收藏  举报

导航