Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions LinuxDump/Analysis.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# !/usr/bin/env python
# -*- coding: utf-8 -*-
# module LinuxDump.Analysis
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab:
#
# --------------------------------------------------------------------
# (C) Copyright 2006-2019 Hewlett Packard Enterprise Development LP
Expand Down Expand Up @@ -29,8 +30,8 @@

from LinuxDump.inet import proto
from LinuxDump.Tasks import (TaskTable, Task, tasksSummary, ms2uptime,
decode_tflags, decode_waitq, TASK_STATE)

decode_tflags, decode_waitq, TASK_STATE,
getTaskState)
from LinuxDump.fregsapi import (search_for_registers, DisasmFlavor)
from LinuxDump.BTstack import (exec_bt, verifyFastSet)

Expand Down Expand Up @@ -244,7 +245,7 @@ def print_pidlist(pids, title = '', verbose = False, maxpids = 10,
def check_possible_hang():
T_table = TaskTable()
pids_UN = {t.pid for t in T_table.allThreads() \
if t.ts.state & TASK_STATE.TASK_UNINTERRUPTIBLE}
if getTaskState(t.ts) & TASK_STATE.TASK_UNINTERRUPTIBLE}
tot_UN = len(pids_UN)
# Now check how many pids are older than 120s
mlist = []
Expand Down Expand Up @@ -278,7 +279,7 @@ def check_memory_pressure(_funcpids):
T_table = TaskTable()
for pid in subpids:
t = T_table.getByTid(pid)
d[t.state] += 1
d[getTaskState(t)] += 1
total += 1
if ("TASK_UNINTERRUPTIBLE" in d or total > 20):
pylog.warning("Memory pressure detected")
Expand All @@ -295,7 +296,7 @@ def check_hanging_nfsd(_funcpids):
T_table = TaskTable()
for pid in subpids:
t = T_table.getByTid(pid)
d[t.state] += 1
d[getTaskState(t)] += 1
total += 1
if ("TASK_UNINTERRUPTIBLE" in d):
pylog.warning("Hanging nfsd threads")
Expand Down
66 changes: 64 additions & 2 deletions LinuxDump/Tasks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# module LinuxDump.Tasks
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab:
#
# --------------------------------------------------------------------
# (C) Copyright 2006-2020 Hewlett Packard Enterprise Development LP
Expand Down Expand Up @@ -28,7 +29,7 @@
from pykdump.API import *
from pykdump.ASCII_Art import EmbeddedFrames

from LinuxDump import percpu
from LinuxDump import percpu, crashcolor

from .inet import proto
from .BTstack import exec_bt
Expand Down Expand Up @@ -127,6 +128,67 @@
else:
TASK_STATE = TASK_STATE_26

# task_struct.__state was task_struct.state
# try the new name and fallback to the old.
def getTaskState(task):
state = None
try:
state = task.__state
except KeyError as kerr: # older kernel, pre 5.14?
state = task.state
return state

## From pstree.py, shared with taskinfo.py
TASK_RUNNING = 0
TASK_INTERRUPTIBLE = 1
TASK_UNINTERRUPTIBLE = 2
__TASK_STOPPED = 4
__TASK_TRACED = 8
EXIT_ZOMBIE = 16
EXIT_DEAD = 32
TASK_DEAD = 64

def task_state_color(state):
if isinstance(state, int):
state = state & 0x7f
return {
TASK_RUNNING : crashcolor.BLUE,
TASK_INTERRUPTIBLE : crashcolor.RESET,
TASK_UNINTERRUPTIBLE : crashcolor.RED,
__TASK_STOPPED : crashcolor.CYAN,
__TASK_TRACED : crashcolor.MAGENTA,
EXIT_ZOMBIE : crashcolor.YELLOW,
EXIT_DEAD : crashcolor.LIGHTRED,
TASK_DEAD : crashcolor.LIGHTRED,
"TASK_RUNNING" : crashcolor.BLUE,
"TASK_INTERRUPTIBLE" : crashcolor.RESET,
"TASK_UNINTERRUPTIBLE" : crashcolor.RED,
"TASK_STOPPED" : crashcolor.CYAN,
"TASK_ZOMBIE" : crashcolor.YELLOW,
"TASK_DEAD" : crashcolor.LIGHTRED,
}[state]


def task_state_str(state):
if isinstance(state, int):
state = state & 0x7f
return {
TASK_RUNNING: "RU",
TASK_INTERRUPTIBLE: "IN",
TASK_UNINTERRUPTIBLE: "UN",
__TASK_STOPPED: "ST",
__TASK_TRACED: "TR",
EXIT_ZOMBIE: "ZO",
EXIT_DEAD: "DE",
TASK_DEAD: "DE",
"TASK_RUNNING" : "RU",
"TASK_INTERRUPTIBLE" : "IN",
"TASK_UNINTERRUPTIBLE" : "UN",
"TASK_STOPPED" : "ST",
"TASK_ZOMBIE" : "ZO",
"TASK_DEAD" : "DE",
}[state]

# -------------------------------------------------------------------

# We have a global variable 'struct task_struct init_task;',
Expand Down Expand Up @@ -185,7 +247,7 @@ def __get_rq(self):
# -- Get Task State in a symbolic format --
def __get_state(self):
try:
st = task_state2str(self.ts.state)
st = getTaskState(self.ts)
except:
st = '??'
pylog.error('corrupted task ', self.ts)
Expand Down
4 changes: 2 additions & 2 deletions progs/crashinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
fastSubroutineStacks, verifyFastSet)
from LinuxDump.kmem import parse_kmemf, print_Zone
from LinuxDump.Tasks import (TaskTable, Task, tasksSummary, getRunQueues,
TASK_STATE, sched_clock2ms, decode_waitq)
TASK_STATE, sched_clock2ms, decode_waitq, getTaskState)
from LinuxDump.Analysis import (check_possible_hang, check_saphana,
check_memory_pressure, check_hanging_nfsd,
print_wait_for_AF_UNIX)
Expand Down Expand Up @@ -992,7 +992,7 @@ def check_UNINTERRUPTIBLE():
bts = []
count = 0
for t in tt.allThreads():
if (t.ts.state & TASK_STATE.TASK_UNINTERRUPTIBLE):
if (getTaskState(t.ts) & TASK_STATE.TASK_UNINTERRUPTIBLE):
pid = t.pid
count += 1
# crash can miss some threads when there are pages missing
Expand Down
9 changes: 5 additions & 4 deletions progs/hanginfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
from pykdump.API import *
from LinuxDump.fs import *
from LinuxDump.Tasks import (TaskTable, Task, tasksSummary, ms2uptime,
decode_tflags, decode_waitq, TASK_STATE)
decode_tflags, decode_waitq, TASK_STATE,
getTaskState)
from LinuxDump.BTstack import (exec_bt, bt_mergestacks, fastSubroutineStacks,
verifyFastSet)

Expand Down Expand Up @@ -99,7 +100,7 @@ def print_header(msg, n = None):
#@memoize_cond(CU_LIVE)
def getUNTasks():
return {t.pid for t in T_table.allThreads() \
if t.ts.state & TASK_STATE.TASK_UNINTERRUPTIBLE}
if getTaskState(t.ts) & TASK_STATE.TASK_UNINTERRUPTIBLE}

# Remove a list of pids from the provided dictionary
def remove_pidlist(pset, pids):
Expand Down Expand Up @@ -226,7 +227,7 @@ def get_sema_owners():
for t in tt.allThreads():
if (not t.pid in goodpids):
continue
if (t.ts.state in (TASK_STATE.TASK_RUNNING, TASK_STATE.TASK_UNINTERRUPTIBLE)):
if (getTaskState(t.ts) in (TASK_STATE.TASK_RUNNING, TASK_STATE.TASK_UNINTERRUPTIBLE)):
if (member_size("struct mm_struct", "mmap_sem") != -1):
out[t.mm.mmap_sem].append(t.pid)
else:
Expand All @@ -247,7 +248,7 @@ def summarize_subroutines(funcnames, title = None):
total = 0
for pid in subpids:
t = T_table.getByTid(pid)
d[t.state] += 1
d[getTaskState(t)] += 1
total += 1
# Print
if (title):
Expand Down
62 changes: 6 additions & 56 deletions progs/pstree.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env/python
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab:
# --------------------------------------------------------------------
# (C) Copyright 2018-2019 Red Hat, Inc.
#
Expand All @@ -21,7 +22,8 @@
# GNU General Public License for more details.
from pykdump.API import *

from LinuxDump.Tasks import Task, TaskTable
from LinuxDump.Tasks import (Task, TaskTable, getTaskState,
task_state_color, task_state_str)
from LinuxDump import crashcolor

import sys
Expand Down Expand Up @@ -66,59 +68,6 @@ def print_pstree(options):

print ("\n\nTotal %s tasks printed" % (pid_cnt))

TASK_RUNNING = 0
TASK_INTERRUPTIBLE = 1
TASK_UNINTERRUPTIBLE = 2
__TASK_STOPPED = 4
__TASK_TRACED = 8
EXIT_ZOMBIE = 16
EXIT_DEAD = 32
TASK_DEAD = 64

def task_state_color(state):
if isinstance(state, int):
state = state & 0x7f

return {
TASK_RUNNING : crashcolor.BLUE,
TASK_INTERRUPTIBLE : crashcolor.RESET,
TASK_UNINTERRUPTIBLE : crashcolor.RED,
__TASK_STOPPED : crashcolor.CYAN,
__TASK_TRACED : crashcolor.MAGENTA,
EXIT_ZOMBIE : crashcolor.YELLOW,
EXIT_DEAD : crashcolor.LIGHTRED,
TASK_DEAD : crashcolor.LIGHTRED,
"TASK_RUNNING" : crashcolor.BLUE,
"TASK_INTERRUPTIBLE" : crashcolor.RESET,
"TASK_UNINTERRUPTIBLE" : crashcolor.RED,
"TASK_STOPPED" : crashcolor.CYAN,
"TASK_ZOMBIE" : crashcolor.YELLOW,
"TASK_DEAD" : crashcolor.LIGHTRED,
}[state]


def task_state_str(state):
if isinstance(state, int):
state = state & 0x7f

return {
TASK_RUNNING: "RU",
TASK_INTERRUPTIBLE: "IN",
TASK_UNINTERRUPTIBLE: "UN",
__TASK_STOPPED: "ST",
__TASK_TRACED: "TR",
EXIT_ZOMBIE: "ZO",
EXIT_DEAD: "DE",
TASK_DEAD: "DE",
"TASK_RUNNING" : "RU",
"TASK_INTERRUPTIBLE" : "IN",
"TASK_UNINTERRUPTIBLE" : "UN",
"TASK_STOPPED" : "ST",
"TASK_ZOMBIE" : "ZO",
"TASK_DEAD" : "DE",
}[state]


def print_branch(depth, first):
global branch_locations
global branch_bar
Expand Down Expand Up @@ -167,15 +116,16 @@ def print_task(task, depth, first, options):
if (task.comm != 0):
comm_str = task.comm

task_color = task_state_color(task.state)
state = getTaskState(task)
task_color = task_state_color(state)
if task_color != crashcolor.RESET:
crashcolor.set_color(task_color)

print_str = ("%s%s%s%s " %
(comm_str,
"(" + str(task.pid) + ")"
if options.print_pid else "",
"[" + task_state_str(task.state) +"]"
"[" + task_state_str(state) +"]"
if options.print_state else "",
thread_str))
print ("%s" % (print_str), end='')
Expand Down
20 changes: 11 additions & 9 deletions progs/taskinfo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab:


# --------------------------------------------------------------------
Expand All @@ -17,12 +18,12 @@

from LinuxDump import percpu
from LinuxDump.Tasks import (TaskTable, Task, tasksSummary, ms2uptime,
decode_tflags, print_namespaces_info, print_memory_stats)
decode_tflags, print_namespaces_info, print_memory_stats, getTaskState,
task_state_str)

from LinuxDump.BTstack import exec_bt, bt_summarize
from LinuxDump.fs import get_dentry_name


debug = API_options.debug

# The following is for x86/x86_64
Expand Down Expand Up @@ -72,7 +73,7 @@ def gid_t(v):


def printTaskDetails(t):
sstate = t.state[5:7]
sstate = task_state_str(getTaskState(t))
print ("---- %6d(%s) %s %s" % (t.pid, sstate, str(t.ts), t.comm))
print(" cpu", t.cpu)
parent = t.parent
Expand Down Expand Up @@ -144,13 +145,14 @@ def printTaskDetails(t):
if u.hasField("files"):
print ("\t processes={} files={}{}".format(
atomic_t(u.processes), atomic_t(u.files), extra))
else:
print ("\t processes={}{}".format(
atomic_t(u.processes), extra))
elif u.hasField("processes"):
print ("\t processes={}{}".format(atomic_t(u.processes), extra))
if (c.hasField("group_info")):
g = c.group_info
ngroups = g.ngroups
small_block = g.small_block
small_block = ""
if g.hasField("small_block"):
small_block = g.small_block
else:
ngroups = t.ngroups
small_block = t.groups
Expand Down Expand Up @@ -243,7 +245,7 @@ def printTasks(reverse = False, maxtoprint = -1):
if (taskstates_filter):
out1 = []
for *group, t in out:
sstate = t.state[5:7]
sstate = task_state_str(getTaskState(t))
if (sstate in taskstates_filter):
out1.append((*group, t))
out = out1
Expand All @@ -270,7 +272,7 @@ def printTasks(reverse = False, maxtoprint = -1):
if (pid is None):
print(" <snip>")
continue
sstate = t.state[5:7]
sstate = task_state_str(getTaskState(t))
tgid = t.tgid
pid_template = " {:6d}"
if (pid != tgid):
Expand Down