Skip to content

Conversation

@YassineLr
Copy link
Contributor

No description provided.

@YassineLr
Copy link
Contributor Author

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.
I haven’t added any tests yet -- waiting to see if you think these helpers are worth keeping. Thank you !

Copy link
Owner

@osandov osandov left a 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!

Copy link
Contributor

@brenns10 brenns10 left a 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.

@YassineLr
Copy link
Contributor Author

Thanks a lot @osandov and @brenns10 for the detailed comments! I’ll go through each change you mentioned.

@YassineLr
Copy link
Contributor Author

Hey @osandov @brenns10 Apologies for the delay. I’ve addressed the requested changes, please let me know if there’s anything else you’d like me to adjust.

Copy link
Owner

@osandov osandov left a 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.

return TaskRss(filerss, anonrss, shmemrss, swapents)


def task_vsize(task: Object) -> float:
Copy link
Owner

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?

yield other


def is_group_leader(t: Object) -> bool:
Copy link
Owner

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.


def is_group_leader(t: Object) -> bool:
"""
Check if a task is thread group leader.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document argument type:

Suggested change
Check if a task is thread group leader.
Check if a task is thread group leader.
:param task: ``struct task_struct *``

@YassineLr YassineLr force-pushed the dev/ps branch 2 times, most recently from e206a01 to d648e61 Compare September 29, 2025 17:20
@YassineLr
Copy link
Contributor Author

Hey @osandov @brenns10 , sorry for the delay. I’ve addressed the requested changes and looking forward to your review.

Copy link
Owner

@osandov osandov left a 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!

"-u",
dest="user",
action="store_true",
default=False,
Copy link
Owner

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).

Suggested change
default=False,

Comment on lines 235 to 251
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")
Copy link
Owner

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):
        continue

It also needs to consider the pid/task/command checks.

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")
Copy link
Owner

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

Suggested change
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).

Comment on lines 264 to 266
builder.append(
" last_arrival = format_nanosecond_duration(time_nanosec)\n"
)
Copy link
Owner

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

Suggested change
builder.append(
" last_arrival = format_nanosecond_duration(time_nanosec)\n"
)

builder.add_from_import(
"drgn.helpers.linux.sched", "task_since_last_arrival_ns"
)
builder.add_import("datetime")
Copy link
Owner

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?

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
Copy link
Owner

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.

@osandov osandov linked an issue Dec 8, 2025 that may be closed by this pull request
osandov and others added 7 commits December 11, 2025 11:14
…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]>
@osandov osandov merged commit dc391e5 into osandov:main Dec 11, 2025
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash command: ps

3 participants