아래 패치도 정말 유용하다.
* 유저 프로세스가 ASSET될 때 콜 스택 출력
* 부팅 과정에 오픈하는 파일을 출력
* 실행되는 파일 이름 출력
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 9f5d818..4d6df0c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -37,7 +37,8 @@
#include <asm/tls.h>
#include <asm/system_misc.h>
#include <asm/opcodes.h>
-
+#include <linux/file.h>
+#include <linux/slab.h>
static const char *handler[]= {
"prefetch abort",
@@ -60,6 +61,48 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup);
#endif
+
+void trace_exe_filename(void)
+{
+ struct file *exe_file;
+ char *pathbuf, *fname;
+
+ printk("[+][trace][%s][%s,%d] caller: %pS \n",
+ current->comm, __func__,__LINE__, (void *)__builtin_return_address(0));
+
+ exe_file = get_mm_exe_file(current->mm);
+
+ if (!exe_file)
+ {
+ printk("[-] path unknown: %s \n", current->comm);
+ return;
+ }
+
+ pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
+
+ if (!pathbuf) {
+ printk("[-] memory starved: %s \n", current->comm);
+ goto put_exe_file;
+ }
+
+ fname = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
+
+ if (IS_ERR(fname)) {
+ printk("[-] path error: %s \n", current->comm);
+ goto free_buf;
+ }
+
+ printk("[+][%s]: exe_file: %s \n", current->comm, fname);
+
+free_buf:
+ kfree(pathbuf);
+put_exe_file:
+ fput(exe_file);
+
+ return;
+}
+
+
static void dump_mem(const char *, const char *, unsigned long, unsigned long);
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
@@ -409,6 +452,8 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
siginfo_t info;
void __user *pc;
+ printk("[+][trace][%s][%s,%d]: \n", current->comm, __func__,__LINE__);
+
pc = (void __user *)instruction_pointer(regs);
if (processor_mode(regs) == SVC_MODE) {
@@ -444,14 +489,11 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
return;
die_sig:
-#ifdef CONFIG_DEBUG_USER
- if (user_debug & UDBG_UNDEFINED) {
- printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
+ printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
current->comm, task_pid_nr(current), pc);
- __show_regs(regs);
- dump_instr(KERN_INFO, regs);
- }
-#endif
+ __show_regs(regs);
+ dump_instr(KERN_INFO, regs);
+ trace_exe_filename();
info.si_signo = SIGILL;
info.si_errno = 0;
@@ -508,19 +550,18 @@ static int bad_syscall(int n, struct pt_regs *regs)
struct thread_info *thread = current_thread_info();
siginfo_t info;
+ printk("[+][trace][%s][%s,%d]: \n", current->comm, __func__,__LINE__);
+
if ((current->personality & PER_MASK) != PER_LINUX &&
thread->exec_domain->handler) {
thread->exec_domain->handler(n, regs);
return regs->ARM_r0;
}
-#ifdef CONFIG_DEBUG_USER
- if (user_debug & UDBG_SYSCALL) {
- printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
+ printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
task_pid_nr(current), current->comm, n);
- dump_instr(KERN_ERR, regs);
- }
-#endif
+ dump_instr(KERN_ERR, regs);
+ trace_exe_filename();
info.si_signo = SIGILL;
info.si_errno = 0;
@@ -688,21 +729,15 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
return -ENOSYS;
break;
}
-#ifdef CONFIG_DEBUG_USER
- /*
- * experience shows that these seem to indicate that
- * something catastrophic has happened
- */
- if (user_debug & UDBG_SYSCALL) {
- printk("[%d] %s: arm syscall %d\n",
- task_pid_nr(current), current->comm, no);
- dump_instr("", regs);
- if (user_mode(regs)) {
- __show_regs(regs);
- c_backtrace(frame_pointer(regs), processor_mode(regs));
- }
- }
-#endif
+
+ printk("[%d] %s: arm syscall %d\n",
+ task_pid_nr(current), current->comm, no);
+ dump_instr("", regs);
+ __show_regs(regs);
+ c_backtrace(frame_pointer(regs), processor_mode(regs));
+
+ trace_exe_filename();
+
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_ILLTRP;
@@ -769,14 +804,11 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
unsigned long addr = instruction_pointer(regs);
siginfo_t info;
-#ifdef CONFIG_DEBUG_USER
- if (user_debug & UDBG_BADABORT) {
- printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
+ printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
task_pid_nr(current), current->comm, code, instr);
- dump_instr(KERN_ERR, regs);
- show_pte(current->mm, addr);
- }
-#endif
+ dump_instr(KERN_ERR, regs);
+ show_pte(current->mm, addr);
+ trace_exe_filename();
info.si_signo = SIGILL;
info.si_errno = 0;
diff --git a/fs/exec.c b/fs/exec.c
index b7a5f46..b6089dc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1425,6 +1425,34 @@ int search_binary_handler(struct linux_binprm *bprm)
}
EXPORT_SYMBOL(search_binary_handler);
+#define PROCESS_ARG_BUFF_SIZE 128
+
+void trace_process_exec_profile(const char *fname)
+{
+ char process_arg_buf[PROCESS_ARG_BUFF_SIZE] = {0,};
+ int len = 0;
+
+ len = get_cmdline(current, process_arg_buf, PROCESS_ARG_BUFF_SIZE -1);
+
+ if(len == 0) {
+ pr_info("[-] Error: len: %d \n", len);
+ return;
+ }
+
+ if(!fname) {
+ pr_info("[-] Error: fname null \n");
+ return;
+ }
+
+ if (len > PROCESS_ARG_BUFF_SIZE)
+ len = PROCESS_ARG_BUFF_SIZE;
+
+ process_arg_buf[len] = '\0';
+
+ pr_info("[exec:%s-%d] exec_file: %s, arg: [%s] \n",
+ current->comm, current->pid, fname, process_arg_buf);
+}
+
static int exec_binprm(struct linux_binprm *bprm)
{
pid_t old_pid, old_vpid;
@@ -1442,6 +1470,8 @@ static int exec_binprm(struct linux_binprm *bprm)
trace_sched_process_exec(current, old_pid, bprm);
ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
proc_exec_connector(current);
+
+ trace_process_exec_profile(bprm->filename);
}
return ret;
'[Debugging] Tips' 카테고리의 다른 글
[리눅스][디버깅] GDB로 깨진 콜 스택 복원하기(공유 라이브러리 로딩하는 방법) (0) | 2023.05.04 |
---|---|
[리눅스] GDB 프로그램 사용 위치 파악: 'which -a' (0) | 2023.05.04 |
유용한 TRACE32(T32) 명령어 (0) | 2023.05.04 |
[리눅스커널] 리눅스 커널 브링업 패치 [1] (4.14v) (0) | 2023.05.04 |
[리눅스커널] 디바이스 트리: of_root 디버깅 (0) | 2023.05.04 |