- Bug修复
- Git配置
- Patch生成
- Patch提交
- 参考
之前使用QEMU和GDB调试Linux内核(详见Linux/Debug/相关文章),最后使用内核提供的GDB扩展功能获取当前运行进程,发现内核已经不再使用thread_info获取当前进程,而是使用Per-CPU变量。而且从内核4.9版本开始,thread_info也不再位于内核栈底部,然而内核提供的辅助调试函数lx_thread_info()仍然通过内核栈底地址获取thread_info,很明显这是个Bug,于是决定将其修复并提交一个内核Patch,提交后很快就得到内核维护人员的回应,将Patch提交到了内核主分支。
Linux内核Patch提交还是采用邮件列表方式,不过提供了自动化工具。
Bug修复
Bug的原因已经很明确了,先看下问题代码scripts/gdb/linux/tasks.py:
def get_thread_info(task):
thread_info_ptr_type = thread_info_type.get_type().pointer()
if utils.is_target_arch("ia64"):
...
else:
thread_info = task['stack'].cast(thread_info_ptr_type)
return thread_info.dereference()
还是使用的老的流程,通过栈底地址获取thread_info。
从内核4.9版本开始,已将thread_info移到了task_struct(include\linux\sched.h),而且一定是第一个字段:
struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
* For reasons of header soup (see current_thread_info()), this
* must be the first element of task_struct.
*/
struct thread_info thread_info;
#endif
...
}
所以修复很简单,只需要判断task的第一个字段是否为thread_info,如果是,则直接将其返回;如果不是,还是走原先的流程:
$ git diff ./
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
index 1bf949c43b76..f6ab3ccf698f 100644
--- a/scripts/gdb/linux/tasks.py
+++ b/scripts/gdb/linux/tasks.py
@@ -96,6 +96,8 @@ def get_thread_info(task):
thread_info_addr = task.address + ia64_task_size
thread_info = thread_info_addr.cast(thread_info_ptr_type)
else:
+ if task.type.fields()[0].type == thread_info_type.get_type():
+ return task['thread_info']
thread_info = task['stack'].cast(thread_info_ptr_type)
return thread_info.dereference()
Git配置
添加用户和Email配置,用于git send-email发送Patch。
这里使用Gmail邮箱服务,在Linux项目.git/config配置中添加如下内容:
[user]
name = Xi Kangjie
email = [email protected]
[sendemail]
smtpEncryption = tls
smtpServer = smtp.gmail.com
smtpUser = [email protected]
smtpServerPort = 587
注意在Google账户配置中允许不够安全的应用登陆,否则后面发送Patch会收到如下警告:
Patch生成
Bug修复后,先检查下代码是否符合规范:
$ ./scripts/checkpatch.pl --file scripts/gdb/linux/tasks.py
total: 0 errors, 0 warnings, 137 lines checked
scripts/gdb/linux/tasks.py has no obvious style problems and is ready for submission.
没问题就可以写提交日志了:
$ git add scripts/gdb/linux/tasks.py
$ git commit -s
-s自动添加签发人Signed-off-by: Xi Kangjie
将最近一次提交生成Patch:
$ git format-patch HEAD~
0001-scripts-gdb-fix-get_thread_info.patch
再次检查Patch是否符合规范:
$ ./scripts/checkpatch.pl 0001-scripts-gdb-fix-get_thread_info.patch
ERROR: Please use git commit description style 'commit <12+ chars of sha1> ("")' - ie: 'commit c65eacbe290b ("sched/core: Allow putting thread_info into task_struct")'
#10:
- c65eacbe290b (sched/core: Allow putting thread_info into task_struct)
ERROR: Please use git commit description style 'commit <12+ chars of sha1> ("")' - ie: 'commit 15f4eae70d36 ("x86: Move thread_info into task_struct")'
#11:
- 15f4eae70d36 (x86: Move thread_info into task_struct)
total: 2 errors, 0 warnings, 8 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
0001-scripts-gdb-fix-get_thread_info.patch has style problems, please review.
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
看来格式有错误,引用的提交描述不符合规范,直接修改Patch文件,再次检查:
$ ./scripts/checkpatch.pl 0001-scripts-gdb-fix-get_thread_info.patch
total: 0 errors, 0 warnings, 8 lines checked
0001-scripts-gdb-fix-get_thread_info.patch has no obvious style problems and is ready for submission.
Patch提交
获取Patch相关维护人员:
$ ./scripts/get_maintainer.pl 0001-scripts-gdb-fix-get_thread_info.patch
Jan Kiszka (supporter:GDB KERNEL DEBUGGING HELPER SCRIPTS)
Kieran Bingham (supporter:GDB KERNEL DEBUGGING HELPER SCRIPTS)
Xi Kangjie (commit_signer:1/1=100%,authored:1/1=100%,added_lines:2/2=100%)
linux-kernel@vger.kernel.org (open list)
发送Patch:
$ git send-email --to jan.kiszka@siemens.com --to kieran@bingham.xyz --cc linux-kernel@vger.kernel.org 0001-scripts-gdb-fix-get_thread_info.patch
0001-scripts-gdb-fix-get_thread_info.patch
(mbox) Adding cc: Xi Kangjie from line 'From: Xi Kangjie '
(body) Adding cc: Xi Kangjie from line 'Signed-off-by: Xi Kangjie '
From: Xi Kangjie
To: jan.kiszka@siemens.com,
kieran@bingham.xyz
Cc: linux-kernel@vger.kernel.org,
Xi Kangjie
Subject: [PATCH] scripts/gdb: fix get_thread_info
Date: Thu, 18 Jan 2018 21:01:59 +0000
Message-Id: <20180118210159.17223-1-imxikangjie@gmail.com>
X-Mailer: git-send-email 2.13.2
The Cc list above has been expanded by additional
addresses found in the patch commit message. By default
send-email prompts before sending whenever this occurs.
This behavior is controlled by the sendemail.confirm
configuration setting.
For additional information, run 'git send-email --help'.
To retain the current behavior, but squelch this message,
run 'git config --global sendemail.confirm auto'.
Send this email? ([y]es|[n]o|[q]uit|[a]ll): y
Password for 'smtp://imxikangjie@gmail.com@smtp.gmail.com:587':
OK. Log says:
Server: smtp.gmail.com
MAIL FROM:
RCPT TO:
RCPT TO:
RCPT TO:
RCPT TO:
From: Xi Kangjie
To: jan.kiszka@siemens.com,
kieran@bingham.xyz
Cc: linux-kernel@vger.kernel.org,
Xi Kangjie
Subject: [PATCH] scripts/gdb: fix get_thread_info
Date: Thu, 18 Jan 2018 21:01:59 +0000
Message-Id: <20180118210159.17223-1-imxikangjie@gmail.com>
X-Mailer: git-send-email 2.13.2
Result: 250 2.0.0 OK 1516281059 v9sm14814354pfj.88 - gsmtp
提交成功后,就能在内核邮件列表中看到自己的邮件[[PATCH] scripts/gdb: fix get_thread_info](https://lkml.org/lkml/2018/1/18/291),以及维护人员的回复[Re: [PATCH] scripts/gdb: fix get_thread_info](https://lkml.org/lkml/2018/1/18/516)。
Linux内核被划分成不同的子系统,如网络、内存管理等,不同的子系统有相应的维护人员,一个Patch会首先提交到子系统分支,再被维护人员提交到主分支。
我的Patch被提交到了mm-tree(维护人员是Andrew Morton),见mm-commits邮件列表scripts-gdb-fix-get_thread_info.patch added to -mm tree,Andrew Morton确认没问题后,会将Patch发送给Linus Torvalds,见mm-commits[patch 4/6] scripts/gdb/linux/tasks.py: fix get_thread_info,我的Patch还被发送给了stable分支,见stable邮件列表[patch 4/6] scripts/gdb/linux/tasks.py: fix get_thread_info。
最终由Linus Torvalds将Patch合并到主分支,scripts/gdb/linux/tasks.py: fix get_thread_info。
看到自己的代码在世界的某个角落运转,推动世界向前发展,才是真正的享受。
参考
文章来自: https://consen.github.io/2018/01/19/submit-linux-kernel-patch/
- Submitting patches: the essential guide to getting your code into the kernel
- The perfect patch
- Linux kernel patch format
- git config, git format-patch and git send-email
- GDB Python API Values From Inferior and Types In Python
- mm tree