-
Notifications
You must be signed in to change notification settings - Fork 199
Add Ps crash command #519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Ps crash command #519
Conversation
|
Hey, I added some helper functions but couldn’t find kernel equivalents for example they usually access virtual memory size directly from task_struct rather than wrapping it in a helper. |
osandov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only looked at the helpers this time around, a few comments there. I know you're just adapting these from drgn-tools, so thanks for your patience!
brenns10
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @YassineLr and @osandov , I meant to get this out sooner. I left out comments on the helpers since Omar took a look there. I did some light review on the ps implementation itself.
osandov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this is a cool command. I left some comments throughout, some about the output format, some about the helpers, some on the code style.
The commits also need to be cleaned up. Please rebase to get rid of those merge commits and split the helpers out into their own commit (you can have a separate commit per helper or just put them together, up to you, but please have them separate from the actual command). The helpers also need test cases.
drgn/helpers/linux/mm.py
Outdated
| return TaskRss(filerss, anonrss, shmemrss, swapents) | ||
|
|
||
|
|
||
| def task_vsize(task: Object) -> float: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this return an int?
drgn/helpers/linux/pid.py
Outdated
| yield other | ||
|
|
||
|
|
||
| def is_group_leader(t: Object) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The kernel function is named thread_group_leader(), so let's use that name. The kernel function is in include/linux/sched/signal.h, so let's move this to drgn.helpers.linux.sched, too.
drgn/helpers/linux/pid.py
Outdated
|
|
||
| def is_group_leader(t: Object) -> bool: | ||
| """ | ||
| Check if a task is thread group leader. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document argument type:
| Check if a task is thread group leader. | |
| Check if a task is thread group leader. | |
| :param task: ``struct task_struct *`` |
e206a01 to
d648e61
Compare
osandov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Yassine, sorry for my slow turnaround!
drgn/commands/_builtin/crash/ps.py
Outdated
| "-u", | ||
| dest="user", | ||
| action="store_true", | ||
| default=False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default is automatically False when action="store_true", so you can drop this (and all of the other ones).
| default=False, |
drgn/commands/_builtin/crash/ps.py
Outdated
| if args.user or args.kernel: | ||
| builder.add_from_import("drgn.helpers.linux.kthread", "is_kthread") | ||
| if args.user: | ||
| builder.append( | ||
| "tasks = filter(lambda t: not task_is_kthread(t), for_each_task(prog))\n" | ||
| ) | ||
| elif args.kernel: | ||
| builder.append("tasks = filter(task_is_kthread, for_each_task(prog))\n") | ||
| else: | ||
| builder.append("tasks = for_each_task(prog)\n") | ||
|
|
||
| if args.group_leader: | ||
| builder.add_from_import( | ||
| "drgn.helpers.linux.sched", | ||
| "thread_group_leader", | ||
| ) | ||
| builder.append("tasks = filter(thread_group_leader, tasks)\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than applying these as filters, I think it'd look nicer to make them checks in the for loop. E.g., something like
for task in for_each_task():
if task_is_kthread(task):
continue
if not thread_group_leader(task):
continueIt also needs to consider the pid/task/command checks.
drgn/commands/_builtin/crash/ps.py
Outdated
| builder.append(" total_rss = task_rss.total\n") | ||
| builder.append(" pct_mem = total_rss * 100 / total_mem\n") | ||
| builder.append(" vmem = task_vsize(task)\n") | ||
| builder.append(" command = escape_ascii_string(task.comm.string_())\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to convert this to a string here, just
| builder.append(" command = escape_ascii_string(task.comm.string_())\n") | |
| builder.append(" command = task.comm\n") |
(And you can remove the add_from_import for escape_ascii_string).
drgn/commands/_builtin/crash/ps.py
Outdated
| builder.append( | ||
| " last_arrival = format_nanosecond_duration(time_nanosec)\n" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
format_nanosecond_duration() isn't a public helper. We don't really need to format this, either, so you can just delete it
| builder.append( | |
| " last_arrival = format_nanosecond_duration(time_nanosec)\n" | |
| ) |
drgn/commands/_builtin/crash/ps.py
Outdated
| builder.add_from_import( | ||
| "drgn.helpers.linux.sched", "task_since_last_arrival_ns" | ||
| ) | ||
| builder.add_import("datetime") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't used anywhere, did you intend to use it?
drgn/commands/_builtin/crash/ps.py
Outdated
| print_table, | ||
| ) | ||
| from drgn.helpers.linux.kthread import task_is_kthread | ||
| from drgn.helpers.linux.mm import get_task_rss_info, task_vsize, totalram_pages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI I renamed get_task_rss_info() to task_rss_info(), so you'll want to rebase and update that.
…task() It's often surprising that for_each_task() doesn't actually return every task_struct, as it omits PID 0. It's probably too late now to change the default to include idle threads, but make it an option. The crash ps command will also use this. Signed-off-by: Omar Sandoval <[email protected]>
… and environ() For the crash ps command, it'll be slightly more convenient to get a task's mm and explicitly test it rather than checking for a None return. Signed-off-by: Omar Sandoval <[email protected]>
It's awkward to build the loop body to pass to
DrgnCodeBuilder.{append,wrap}_retry_loop_if_live() and
CrashDrgnCodeBuilder.append_cpuspec(). Replace them with context-based
APIs that automatically add indentation to subsequent appends as needed.
Signed-off-by: Omar Sandoval <[email protected]>
This is needed for the crash ps and foreach commands. Unfortunately, we're forced to hard-code the PF_KTHREAD flag. Signed-off-by: YassineLr <[email protected]> [Omar: rewrite test case] Signed-off-by: Omar Sandoval <[email protected]>
This is needed for the crash ps command. Signed-off-by: YassineLr <[email protected]>
This is needed for the crash ps and foreach commands. Signed-off-by: YassineLr <[email protected]> [Omar: rewrite test case] Signed-off-by: Omar Sandoval <[email protected]>
I believe that this is complete. The implementation of -s is terrible; it does a full stack trace just to get the initial stack pointer, but we can optimize that later. Co-authored-by: YassineLr <[email protected]> Signed-off-by: YassineLr <[email protected]> Signed-off-by: Omar Sandoval <[email protected]>
No description provided.