linux内核调试_如何以更少的努力调试Linux内核

linux内核调试

Introduction

介绍

In general, if we want to debug Linux Kernel, there are lots of tools such as Linux Perf, Kprobe, BCC, Ktap, etc, and we can also write kernel modules, proc subsystems or system calls for some specific debugging aims. However, if we have to instrument kernel to achieve our goals, usually we would not like to pay more efforts like above solutions since we’d like to achieve our aims quickly and easily. In this article, I will introduce a way to debug Linux Kernel with less efforts.

通常,如果要调试Linux内核,则有很多工具,例如Linux Perf,Kprobe,BCC,Ktap等,我们还可以编写内核模块,proc子系统或系统调用以实现某些特定的调试目的。 但是,如果我们必须检测内核以实现我们的目标,通常我们不想像上述解决方案那样付出更多的努力,因为我们希望快速,轻松地实现我们的目标。 在本文中,我将介绍一种用较少的精力调试Linux内核的方法。

Example – Debug Linux Kernel Scheduling Subsystems

示例–调试Linux内核调度子系统

In this example, I want to know how long a thread is executing on one CPU so I would like to add one flag, say ‘enable_flag’, to be one switch for this feature. At the same time, of course, I need to know which thread I would like to debug so I set another parameter, say ‘enable_pid’. See following patch for details.

在此示例中,我想知道一个线程在一个CPU上执行了多长时间,因此我想添加一个标志,例如“ enable_flag”,作为该功能的一个开关。 当然,同时,我需要知道我想调试哪个线程,所以我设置了另一个参数,例如'enable_pid'。 有关详细信息,请参见以下补丁 。


--- ./core.c 2016-11-19 20:17:41.000000000 -0500
+++ /usr/src/linux-3.16.39/kernel/sched/core.c 2017-01-04 22:23:37.419571125 -0500
@@ -90,6 +90,29 @@
#define CREATE_TRACE_POINTS
#include

+//added by Weiwei Jia
+#include +int enable_flag = 0;
+module_param(enable_flag, int, 0664);
+EXPORT_SYMBOL_GPL(enable_flag);
+
+int enable_tick1 = 0;
+module_param(enable_tick1, int, 0664);
+EXPORT_SYMBOL_GPL(enable_tick1);
+
+int enable_tick2 = 0;
+module_param(enable_tick2, int, 0664);
+EXPORT_SYMBOL_GPL(enable_tick2);
+
+int enable_debug = 0;
+module_param(enable_debug, int, 0664);
+EXPORT_SYMBOL_GPL(enable_debug);
+
+int enable_pid = 0;
+module_param(enable_pid, int, 0664);
+EXPORT_SYMBOL_GPL(enable_pid);
+//ended
+
#ifdef smp_mb__before_atomic
void __smp_mb__before_atomic(void)
{
@@ -2797,6 +2820,7 @@
unsigned long *switch_count;
struct rq *rq;
int cpu;
+ s64 diff = 0; //added by Weiwei Jia

need_resched:
preempt_disable();
@@ -2855,6 +2879,29 @@
rq->curr = next;
++*switch_count;

+ //added by Weiwei Jia
+ do_gettimeofday(&(next->__ts));
+ next->__start_ts = (s64) ((next->__ts).tv_sec * 1000000 + (next->__ts).tv_usec);
+ prev->__end_ts = next->__start_ts;
+ if (enable_flag == 1 && prev->pid == enable_pid) {
+ //printk(KERN_INFO "%lld\n", prev->__end_ts - prev->__start_ts);
+ //diff = (prev->se).sum_exec_runtime - (prev->se).prev_sum_exec_runtime;
+ diff = prev->__end_ts - prev->__start_ts;
+ printk(KERN_INFO "%lld\n", diff);
+#if 1
+ printk(KERN_INFO "next process id is %d\n", next->pid);
+ if (diff < 2000) { + printk(KERN_INFO "------------------------------------------\n"); + printk(KERN_INFO "Start timestamp is %lld microseconds\n", prev->__start_ts);
+ printk(KERN_INFO "End timestamp is %lld microseconds\n", prev->__end_ts);
+ printk(KERN_INFO "Timeslice is %lld micorseconds\n\n", diff);
+ dump_stack();
+ printk(KERN_INFO "------------------------------------------\n");
+ }
+#endif
+ }
+ //ended
+
context_switch(rq, prev, next); /* unlocks the rq */
/*
* The context switch have flipped the stack from under us


--- ./core.c 2016-11-19 20:17:41.000000000 -0500
+++ /usr/src/linux-3.16.39/kernel/sched/core.c 2017-01-04 22:23:37.419571125 -0500
@@ -90,6 +90,29 @@
#define CREATE_TRACE_POINTS
#include

+ //由贾伟伟添加
+#include + int enable_flag = 0;
+ module_param(enable_flag,int,0664);
+ EXPORT_SYMBOL_GPL(enable_flag);
+
+ int enable_tick1 = 0;
+ module_param(enable_tick1,int,0664);
+ EXPORT_SYMBOL_GPL(enable_tick1);
+
+ int enable_tick2 = 0;
+ module_param(enable_tick2,int,0664);
+ EXPORT_SYMBOL_GPL(enable_tick2);
+
+ int enable_debug = 0;
+ module_param(enable_debug,int,0664);
+ EXPORT_SYMBOL_GPL(enable_debug);
+
+ int enable_pid = 0;
+ module_param(enable_pid,int,0664);
+ EXPORT_SYMBOL_GPL(enable_pid);
+ //结束
+
#ifdef smp_mb__before_atomic
void __smp_mb__before_atomic(void)
{
@@ -2797,6 +2820,7 @@
无符号长* switch_count;
struct rq * rq;
int cpu;
+ s64 diff = 0; //由贾伟伟添加

need_resched:
preempt_disable();
@@ -2855,6 +2879,29 @@
rq-> curr =接下来;
++ * switch_count;

+ //由贾伟伟添加
+ do_gettimeofday(&(next-> __ ts));
+ next-> __ start_ts =(s64)((next-> __ ts).tv_sec * 1000000 +(next-> __ ts).tv_usec);
+上一个-> __ end_ts =下一个-> __ start_ts;
+ if(enable_flag == 1 && prev-> pid == enable_pid){
+ // printk(KERN_INFO“%lld \ n”,prev-> __ end_ts-prev-> __ start_ts);
+ // diff =(prev-> se).sum_exec_runtime-(prev-> se).prev_sum_exec_runtime;
+ diff = prev-> __ end_ts-prev-> __ start_ts;
+ printk(KERN_INFO“%lld \ n”,diff);
+#if 1
+ printk(KERN_INFO“下一个进程ID为%d \ n”,next-> pid);
+ if(diff <2000){+ printk(KERN_INFO“ ------------------------------------- ----- \ n“); + printk(KERN_INFO“开始时间戳为%lld微秒\ n”,上一个-> __ start_ts);
+ printk(KERN_INFO“结束时间戳为%lld微秒\ n”,上一个-> __ end_ts);
+ printk(KERN_INFO“时间片为%lld毫秒\ n \ n”,差异);
+ dump_stack();
+ printk(KERN_INFO“ ------------------------------------------ \ n” );
+}
+#endif
+}
+ //结束
+
context_switch(rq,prev,next); / *解锁rq * /
/ *
*上下文切换从我们下面翻转了堆栈

“EXPORT_SYMBOL_GPL(enable_flag)” will export this parameter as one file under “/sys/module/core/parameters” directory, and you can write zero or not zero in “/sys/module/core/parameters/enable_flag” so that it will start this feature or not. You will also need to write the thread id into “/sys/module/core/parameters/enable_pid” to debug this specific thread. Now, you will find that this solution is very easy and you will pay less efforts. Please also remember that these parameters can also be used in other places with external definition.

“ EXPORT_SYMBOL_GPL(enable_flag)”将将此参数导出为“ / sys / module / core / parameters”目录下的一个文件,并且您可以在“ / sys / module / core / parameters / enable_flag”中写入零或不为零。是否将启动此功能。 您还需要将线程ID写入“ / sys / module / core / parameters / enable_pid”以调试该特定线程。 现在,您会发现此解决方案非常简单,并且您将花费更少的精力。 还请记住,这些参数也可以在具有外部定义的其他地方使用。

Conclusion

结论

This article presents a easy and quick way for system developers to debug Linux Kernel.

本文为系统开发人员提供了一种便捷的调试Linux内核的方法。

References

参考资料

[1] http://elixir.free-electrons.com/linux/v3.16.39/source

[1] http://elixir.free-electrons.com/linux/v3.16.39/source

翻译自: https://www.systutorials.com/debug-linux-kernel-less-efforts/

linux内核调试

你可能感兴趣的:(内核,linux,java,python,android)