From 16267f9717450b06139a0f41be3e213d44f6c044 Mon Sep 17 00:00:00 2001 From: Serapheim Dimitropoulos Date: Wed, 23 Aug 2023 10:59:26 -0700 Subject: [PATCH] DLPX-87579 sdb: use drgn helper for task states (#341) = Problem Currently having our own custom function for figuring out a task's state has two drawbacks: 1] As we saw in a2bdd57cf33a08f938b2d67c529d331a2ac1cac6 things can get out of date and it is up to us to fix them. 2] There are some weird edge cases that we don't handle as well like the following crash that I have never been able to reproduce locally but it occasionally reproduces in the Github runners of PR https://github.com/delphix/sdb/pull/337: ``` Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/internal/repl.py", line 107, in eval_cmd for obj in invoke([], input_): File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/pipeline.py", line 152, in invoke yield from execute_pipeline(first_input, pipeline) File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/pipeline.py", line 84, in execute_pipeline yield from massage_input_and_call(pipeline[-1], this_input) File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/pipeline.py", line 67, in massage_input_and_call yield from cmd.call(objs) File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/command.py", line 413, in call yield from self.__invalid_memory_objects_check( File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/command.py", line 358, in __invalid_memory_objects_check for obj in objs: File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/command.py", line 625, in _call self.pretty_print(self.caller(objs)) File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/commands/linux/stacks.py", line 407, in pretty_print self.print_stacks(filter(self.match_stack, objs)) File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/commands/linux/stacks.py", line 382, in print_stacks for stack_key, tasks in KernelStacks.aggregate_stacks(objs): File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/commands/linux/stacks.py", line 375, in aggregate_stacks stack_key = (KernelStacks.task_struct_get_state(task), File "/usr/local/lib/python3.8/dist-packages/sdb-0.1.0-py3.8.egg/sdb/commands/linux/stacks.py", line 221, in task_struct_get_state return KernelStacks.TASK_STATES[(state | exit_state) & 0x7f] KeyError: 101 ``` = This Patch Uses the drgn helper whose implementation handles more edge cases and is more probable to stay up to date with the latest kernels while keeping backwards compatibility. = Testing The above stack trace that I was able to reproduce consistently in that PR no longer shows up with this patch. --- sdb/commands/linux/stacks.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/sdb/commands/linux/stacks.py b/sdb/commands/linux/stacks.py index a233d3e..8de3ba3 100644 --- a/sdb/commands/linux/stacks.py +++ b/sdb/commands/linux/stacks.py @@ -23,6 +23,7 @@ import drgn from drgn.helpers.linux.list import list_for_each_entry from drgn.helpers.linux.pid import for_each_task +from drgn.helpers.linux.sched import task_state_to_char import sdb @@ -203,22 +204,13 @@ def _init_parser(cls, name: str) -> argparse.ArgumentParser: "t": 0x08, "X": 0x10, "Z": 0x20, + "P": 0x40, + "I": 0x402, } @staticmethod def task_struct_get_state(task: drgn.Object) -> str: - task_struct_type = task.type_.type - state = 0 - if task_struct_type.has_member('__state'): - state = task.member_('__state').value_() - else: - # For kernels older than v5.14 - state = task.state.value_() - if state == 0x402: - return "IDLE" - - exit_state = task.exit_state.value_() - return KernelStacks.TASK_STATES[(state | exit_state) & 0x7f] + return KernelStacks.resolve_state(task_state_to_char(task)) @staticmethod def resolve_state(tstate: str) -> str: