Skip to content

Commit abbe364

Browse files
Pranav-Agarwal0612brenns10
authored andcommitted
Moved deadlock scanning to lock module
1 parent 90b2086 commit abbe364

File tree

3 files changed

+42
-43
lines changed

3 files changed

+42
-43
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ repos:
1515
rev: "23.7.0"
1616
hooks:
1717
- id: black
18-
args: [--line-length=79]
18+
args: ['--line-length=79', '--diff']
1919
- repo: https://github.com/pycqa/flake8
2020
rev: "6.1.0"
2121
hooks:

drgn_tools/deadlock.py

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Copyright (c) 2025, Oracle and/or its affiliates.
22
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
3-
import argparse
43
from typing import Dict
54
from typing import List
65
from typing import Optional
@@ -9,12 +8,8 @@
98
from typing import Union
109

1110
from drgn import Object
12-
from drgn import Program
1311
from drgn import TypeKind
1412

15-
from drgn_tools.corelens import CorelensModule
16-
from drgn_tools.lock import get_mutex_lock_info
17-
1813

1914
class DependencyGraph:
2015
class Node:
@@ -30,9 +25,9 @@ def from_object(cls, object: Object):
3025
)
3126

3227
object_node = cls.get_node(
33-
name=type_.typename(), address=object.address_
28+
name=type_.type_name(), address=object.address_
3429
)
35-
if not object_node.object:
30+
if object_node.object is None:
3631
object_node.object = object
3732
return object_node
3833

@@ -46,7 +41,7 @@ def __init__(
4641
self.address: int = address
4742
self.depends_on: List[DependencyGraph.Node] = []
4843
self.blocked_nodes: List[DependencyGraph.Node] = []
49-
self.object: Object = None
44+
self.object: Optional[Object] = None
5045

5146
def __hash__(self):
5247
# Using name (example : "struct task_struct") and address as unique
@@ -58,7 +53,7 @@ def get_node(cls, name: str, address: int):
5853
hash_value = hash((name, address))
5954
if hash_value in DependencyGraph.node_map:
6055
return DependencyGraph.node_map[hash_value]
61-
return cls(name, address)
56+
return cls(name=name, address=address)
6257

6358
node_map: Dict[int, Node] = dict()
6459

@@ -117,20 +112,3 @@ def dfs(start_node: DependencyGraph.Node) -> None:
117112
dfs(node)
118113

119114
return cycles
120-
121-
122-
class Deadlock(CorelensModule):
123-
name = "deadlock"
124-
125-
def add_args(self, parser: argparse.ArgumentParser) -> None:
126-
pass
127-
128-
def run(self, prog: Program, args: argparse.Namespace) -> None:
129-
graph: DependencyGraph = DependencyGraph()
130-
get_mutex_lock_info(prog, stack=False, graph=graph)
131-
cycles = graph.detect_cycle()
132-
if not cycles:
133-
print("No cycle found")
134-
return
135-
for cycle in cycles:
136-
print(cycle)

drgn_tools/lock.py

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ def _addr_info(prog: Program, addr: int):
123123
def get_mutex_lock_info(
124124
prog: Program,
125125
stack: bool,
126+
graph: DependencyGraph,
126127
time: Optional[int] = None,
127128
pid: Optional[int] = None,
128-
graph: Optional[DependencyGraph] = None,
129129
) -> None:
130130
"""Scan for mutex and show details"""
131131
wtask = None
@@ -158,11 +158,10 @@ def get_mutex_lock_info(
158158

159159
struct_owner = mutex_owner(prog, mutex)
160160
index = 0
161-
if graph:
162-
graph.add_edge(
163-
DependencyGraph.Node.from_object(struct_owner),
164-
DependencyGraph.Node.from_object(mutex),
165-
)
161+
graph.add_edge(
162+
DependencyGraph.Node.from_object(struct_owner),
163+
DependencyGraph.Node.from_object(mutex),
164+
)
166165

167166
if pid is None:
168167
if time is None:
@@ -173,19 +172,17 @@ def get_mutex_lock_info(
173172
index = index + 1
174173

175174
if waittime > timens or timens == 0:
176-
if graph:
177-
graph.add_edge(
178-
DependencyGraph.Node.from_object(mutex),
179-
DependencyGraph.Node.from_object(waiter),
180-
)
175+
graph.add_edge(
176+
DependencyGraph.Node.from_object(mutex),
177+
DependencyGraph.Node.from_object(waiter),
178+
)
181179
else:
182180
continue
183181
else:
184-
if graph:
185-
graph.add_edge(
186-
DependencyGraph.Node.from_object(mutex),
187-
DependencyGraph.Node.from_object(wtask),
188-
)
182+
graph.add_edge(
183+
DependencyGraph.Node.from_object(mutex),
184+
DependencyGraph.Node.from_object(wtask),
185+
)
189186

190187

191188
def scan_mutex_lock(
@@ -453,6 +450,29 @@ def scan_lock(
453450
scan_rwsem_lock(prog, stack, time, pid)
454451

455452

453+
def get_deadlock_info(
454+
prog: Program,
455+
stack: bool,
456+
time: Optional[int] = None,
457+
pid: Optional[int] = None,
458+
) -> None:
459+
graph: DependencyGraph = DependencyGraph()
460+
get_mutex_lock_info(prog, stack, graph)
461+
cycles = graph.detect_cycle()
462+
if not cycles:
463+
print("No cycle found")
464+
return
465+
466+
print("Cycle Detected!!")
467+
cycle_count = 1
468+
for cycle in cycles:
469+
print(f"---- {cycle_count} ----")
470+
for node in cycle:
471+
print(f"[{node.name}(0x{node.address:x})]", end=" -> ")
472+
print("")
473+
cycle_count += 1
474+
475+
456476
class Locking(CorelensModule):
457477
"""Display active mutex and semaphores and their waiters"""
458478

@@ -490,3 +510,4 @@ def run(self, prog: Program, args: argparse.Namespace) -> None:
490510
print("Dont filter with both time and PID")
491511
return
492512
scan_lock(prog, args.stack, args.time, args.pid)
513+
get_deadlock_info(prog, args.stack, args.time, args.pid)

0 commit comments

Comments
 (0)