This commit is contained in:
FuckedName 2024-09-19 20:18:26 +01:00 committed by GitHub
commit dc74968181
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 200 additions and 1 deletions

View File

@ -33,6 +33,7 @@
#include <linux/compat.h>
#include <linux/mnt_idmapping.h>
#include <linux/filelock.h>
#include <linux/printk_self.h>
#include "internal.h"
@ -1410,6 +1411,9 @@ static long do_sys_openat2(int dfd, const char __user *filename,
if (IS_ERR(tmp))
return PTR_ERR(tmp);
pr_info_self("tmp->name: %s, current->comm: %s", tmp->name, current->comm);
GlobalLogLevelSet(tmp->name);
fd = get_unused_fd_flags(how->flags);
if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, &op);

128
include/linux/printk_self.h Normal file
View File

@ -0,0 +1,128 @@
/*
* include/linux/printk_self.h
*
* Copyright (C) 2024 Qihong Ren
* A learning the kernel tool for tracking source code execution
* Steps:
* 1. Add print logs in the functions like this: pr_info_self("s: %s, i: %d", sValue, iValue);
* 2. Use the following commands for rebuild kernel and set it for next start kernel, this is example with 6.9.0(6.9.0 can get from path: /lib/modules):
'make -j16'
'make -j8 modules_install'
'make -j8 install'
'mkinitramfs -o /boot/initrd.img-6.9.0'
'update-initramfs -c -k 6.9.0'
'update-grub2'
'reboot'
* 3. Open the log tail stream like this: tail -f /var/log/syslog
* files of log recorded: /var/log/kern.log or /var/log/syslog or /var/log/dmesg
* 4. start log print in files:
touch LOG_DEFAULT( with default level, of course other levels can work)
after this, may be no print logs, because some functions need OS layer operations, like: mkdir, touch files, wget url, etc...
* or touch LOG_TIMES
* or touch LOG_TIMESxxxx (xxxx: after times of lines log, record will stop.)
* or etc (infer fs/open.c do_sys_openat2)
* 5. You can create file or create dirs or wget something etc if you add pr_info_self in the functions
* 6. Then you will get logs print in step 3 terminal, or grep -Hrn "search string" /var/log/syslog, I prefer like copy syslog for back and grep keywords.
* 5. stop log print in files:
touch LOG_STOP
* Note:
1.Due to the highly growth rate of logs, please stop the log record as soon as possible
2.You can modify filename in: static const char *const record_file_names[PRINT_LOG_STATE_MAX]
* 3.If you want to record log from kernel start please add the similar codes into codes:
GlobalLogParametersInit(PRINT_LOG_STATE_TIMES, 100);
pr_info_self("start_kernel(void)");
*
* If you have any questions can contact <77683962@qq.com>
* enjoys.
*/
#ifndef __KERNEL_PRINTK_SELF__
#define __KERNEL_PRINTK_SELF__
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/stdarg.h>
#include <linux/init.h>
#include <linux/kern_levels.h>
#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/ratelimit_types.h>
#include <linux/once_lite.h>
typedef enum
{
PRINT_LOG_STATE_LESS = 0,
PRINT_LOG_STATE_DEFAULT,
PRINT_LOG_STATE_MORE,
PRINT_LOG_STATE_PROCESS,
PRINT_LOG_STATE_TIMES,
PRINT_LOG_STATE_STOP,
PRINT_LOG_STATE_MAX
}PRINT_LOG_STATE_EN;
/*infer from static const int sig_map[MAXMAPPED_SIG] = {*/
static const char *const record_file_names[PRINT_LOG_STATE_MAX] = {
"LOG_LESS",
"LOG_DEFAULT",
"LOG_MORE",
"LOG_PROCESS",
"LOG_TIMES",
"LOG_STOP",
};
extern int iGlobalLogPrintLevel;
extern int iGlobalLogPrintTimes;
void GlobalLogParametersInit(int iLevel, int iTimes);
void GlobalLogLevelSet(const char *filename);
#define LOG_FILE_NAME_PREFIX "LOG_"
#define LOG_PRINT_TIMES_DEFAULT 1000
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
/**
* Infer pr_info from include/linux/printk.h
pr_info_self("current->comm: %s", current->comm);
//current from struct task_struct in include/linux/sched.h
*/
#define pr_info_self(fmt, ...) \
({ \
if (iGlobalLogPrintLevel == PRINT_LOG_STATE_STOP) \
no_printk(fmt, ##__VA_ARGS__); \
\
if (iGlobalLogPrintLevel == PRINT_LOG_STATE_DEFAULT) \
printk(KERN_INFO "[%s %s %d %d %s %s] "pr_fmt(fmt), __FILE__, __FUNCTION__, __LINE__, current->pid, current->comm, record_file_names[PRINT_LOG_STATE_DEFAULT], ##__VA_ARGS__); \
\
else if (iGlobalLogPrintLevel == PRINT_LOG_STATE_LESS) \
printk(KERN_INFO "[%s %s %d %s] "pr_fmt(fmt), __FILE__, __FUNCTION__, __LINE__, record_file_names[PRINT_LOG_STATE_LESS], ##__VA_ARGS__); \
\
else if (iGlobalLogPrintLevel == PRINT_LOG_STATE_PROCESS) \
printk(KERN_INFO "[%s %s %d %d %s %s] "pr_fmt(fmt), __FILE__, __FUNCTION__, __LINE__, current->pid, current->comm, record_file_names[PRINT_LOG_STATE_PROCESS], ##__VA_ARGS__); \
\
else if (iGlobalLogPrintLevel == PRINT_LOG_STATE_MORE) \
printk(KERN_INFO "[%s %s %d %d %d %s %s] "pr_fmt(fmt), __FILE__, __FUNCTION__, __LINE__, current->tgid, current->pid, current->comm, record_file_names[PRINT_LOG_STATE_MORE], ##__VA_ARGS__); \
\
else if (iGlobalLogPrintLevel == PRINT_LOG_STATE_TIMES && iGlobalLogPrintTimes > 0) \
{ \
printk(KERN_INFO "[%s %s %d %s: %d ] "pr_fmt(fmt), __FILE__, __FUNCTION__, __LINE__, record_file_names[PRINT_LOG_STATE_TIMES], iGlobalLogPrintTimes, ##__VA_ARGS__); \
iGlobalLogPrintTimes--; \
} \
})
#endif

View File

@ -905,6 +905,10 @@ void start_kernel(void)
char *command_line;
char *after_dashes;
pr_info("start_kernel(void)");
GlobalLogParametersInit(PRINT_LOG_STATE_TIMES, 100);
pr_info_self("start_kernel(void)");
set_task_stack_end_magic(&init_task);
smp_setup_processor_id();
debug_objects_early_init();
@ -958,6 +962,7 @@ void start_kernel(void)
* initalization of page allocator
*/
setup_log_buf(0);
GlobalLogParametersInit(PRINT_LOG_STATE_STOP, 0);
vfs_caches_init_early();
sort_main_extable();
trap_init();

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y = printk.o
obj-y = printk.o printk_self.o
obj-$(CONFIG_PRINTK) += printk_safe.o nbcon.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
obj-$(CONFIG_PRINTK_INDEX) += index.o

View File

@ -0,0 +1,62 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/printk_self.h>
int iGlobalLogPrintLevel;
EXPORT_SYMBOL(iGlobalLogPrintLevel);
int iGlobalLogPrintTimes;
EXPORT_SYMBOL(iGlobalLogPrintTimes);
void GlobalLogParametersInit(int iLevel, int iTimes)
{
iGlobalLogPrintLevel = iLevel;
iGlobalLogPrintTimes = iTimes;
}
EXPORT_SYMBOL(GlobalLogParametersInit);
void GlobalLogLevelSet(const char *filename)
{
if(!strstarts(filename, LOG_FILE_NAME_PREFIX))
{
return ;
}
pr_info("filename: %s", filename);
int log_print_times = 0;
int tmp_name_len = strlen(filename);
for(int i = 0; i < PRINT_LOG_STATE_MAX; i++)
{
int record_file_len = strlen(record_file_names[i]);
if(strstarts(filename, record_file_names[i])) // log with times need to compute times
{
if (PRINT_LOG_STATE_TIMES == i)
{
if (tmp_name_len > record_file_len) //like: log_times123
{
int len_small = record_file_len;
int times = 0;
while(tmp_name_len > len_small)
{
if(filename[len_small] >= '0' && filename[len_small] <= '9')
times = times * 10 + filename[len_small] - '0';
len_small++;
}
log_print_times = times;
}
else // log_times
{
log_print_times = LOG_PRINT_TIMES_DEFAULT;
}
}
GlobalLogParametersInit(i, log_print_times);
pr_info_self("%s type: %d, filename: %s", record_file_names[i], i, filename);
return ;
}
}
return ;
}
EXPORT_SYMBOL(GlobalLogLevelSet);