#include
#include
#include
#include
#include
#include
#include
struct dentry *dumpps_dir = NULL;
#define USER_BUF_PAGE 4096
static ssize_t pid_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
char *tmpbuf;
pid_t upid;
struct task_struct *task, *p;
struct pid *pid = NULL;
if (len == 0)
return 0;
if (len > USER_BUF_PAGE - 1) {
pr_warn("expected <%d bytes pid file\n", USER_BUF_PAGE);
return -E2BIG;
}
tmpbuf = memdup_user_nul(ubuf, len);
if (IS_ERR(tmpbuf))
return PTR_ERR(tmpbuf);
pr_info("read %d bytes from userspace\n", (int)len);
upid = simple_strtol(tmpbuf, NULL, 10);
pr_info("write pid=%d\n", upid);
kfree(tmpbuf);
pid = find_get_pid(upid);
task = get_pid_task(pid, PIDTYPE_TGID);
for_each_thread(task, p) {
sched_show_task(p);
}
put_task_struct(task);
put_pid(pid);
*offp += len;
return len;
}
static const struct file_operations pid_fops = {
.owner = THIS_MODULE,
.write = pid_write
};
static int __init dumpps_init(void)
{
dumpps_dir = debugfs_create_dir("dumpps", NULL);
debugfs_create_file("pid", S_IFREG | S_IRUGO, dumpps_dir, NULL, &pid_fops);
return 0;
}
static void __exit dumpps_exit(void)
{
if(dumpps_dir){
debugfs_remove(dumpps_dir);
dumpps_dir = NULL;
}
}
module_init(dumpps_init);
module_exit(dumpps_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("LiuZhongzhi");
MODULE_DESCRIPTION("Dump process stack");