Skip to content

Commit

Permalink
DLPX-87579 sdb: use drgn helper for task states (#341)
Browse files Browse the repository at this point in the history
= Problem

Currently having our own custom function for figuring out a task's
state has two drawbacks:

1] As we saw in a2bdd57 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 #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.
  • Loading branch information
sdimitro authored Aug 23, 2023
1 parent 3a1fadc commit 16267f9
Showing 1 changed file with 4 additions and 12 deletions.
16 changes: 4 additions & 12 deletions sdb/commands/linux/stacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 16267f9

Please sign in to comment.