From 77f5252d158de70d087817b96f865f851ffda259 Mon Sep 17 00:00:00 2001 From: zcy Date: Fri, 28 May 2021 00:50:23 +0800 Subject: [PATCH] tools/deadlock: support specifies maxnum of threads and edge cases (#3455) support to specify maxinum of threads and edge cases. The default values make map taking more than 0.5G memory which cause out-of-memory issue on some systems. also fix an issue with python `open` so the open file is automatically closed upon file reading is done. --- man/man8/deadlock.8 | 8 ++++++++ tools/deadlock.c | 4 ++-- tools/deadlock.py | 16 +++++++++++++++- tools/deadlock_example.txt | 6 ++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/man/man8/deadlock.8 b/man/man8/deadlock.8 index 0be3f4ab..3e7744ce 100644 --- a/man/man8/deadlock.8 +++ b/man/man8/deadlock.8 @@ -58,6 +58,14 @@ These symbols cannot be inlined in the binary. Comma-separated list of unlock symbols to trace. Default is pthread_mutex_unlock. These symbols cannot be inlined in the binary. .TP +\-t THREADS, --threads THREADS +Specifies the maximum number of threads to trace. default 65536. +Note. 40 bytes per thread. +.TP +\-e EDGES, --edges EDGES +Specifies the maximum number of edge cases that can be +recorded. default 65536. Note. 88 bytes per edge case. +.TP pid Pid to trace .SH EXAMPLES diff --git a/tools/deadlock.c b/tools/deadlock.c index b34a207d..006dc121 100644 --- a/tools/deadlock.c +++ b/tools/deadlock.c @@ -30,7 +30,7 @@ struct thread_to_held_mutex_leaf_t { }; // Map of thread ID -> array of (mutex addresses, stack id) -BPF_HASH(thread_to_held_mutexes, u32, struct thread_to_held_mutex_leaf_t, 2097152); +BPF_HASH(thread_to_held_mutexes, u32, struct thread_to_held_mutex_leaf_t, MAX_THREADS); // Key type for edges. Represents an edge from mutex1 => mutex2. struct edges_key_t { @@ -47,7 +47,7 @@ struct edges_leaf_t { }; // Represents all edges currently in the mutex wait graph. -BPF_HASH(edges, struct edges_key_t, struct edges_leaf_t, 2097152); +BPF_HASH(edges, struct edges_key_t, struct edges_leaf_t, MAX_EDGES); // Info about parent thread when a child thread is created. struct thread_created_leaf_t { diff --git a/tools/deadlock.py b/tools/deadlock.py index 81122adb..d6046c24 100755 --- a/tools/deadlock.py +++ b/tools/deadlock.py @@ -457,6 +457,16 @@ def main(): help='Comma-separated list of unlock symbols to trace. Default is ' 'pthread_mutex_unlock. These symbols cannot be inlined in the binary.', ) + parser.add_argument( + '-t', '--threads', type=int, default=65536, + help='Specifies the maximum number of threads to trace. default 65536. ' + 'Note. 40 bytes per thread.' + ) + parser.add_argument( + '-e', '--edges', type=int, default=65536, + help='Specifies the maximum number of edge cases that can be recorded. ' + 'default 65536. Note. 88 bytes per edge case.' + ) args = parser.parse_args() if not args.binary: try: @@ -465,7 +475,11 @@ def main(): print('%s. Is the process (pid=%d) running?' % (str(e), args.pid)) sys.exit(1) - bpf = BPF(src_file=b'deadlock.c') + with open('deadlock.c') as f: + text = f.read() + text = text.replace(b'MAX_THREADS', str(args.threads)); + text = text.replace(b'MAX_EDGES', str(args.edges)); + bpf = BPF(text=text) # Trace where threads are created bpf.attach_kretprobe(event=bpf.get_syscall_fnname('clone'), fn_name='trace_clone') diff --git a/tools/deadlock_example.txt b/tools/deadlock_example.txt index 45d81260..559ce028 100644 --- a/tools/deadlock_example.txt +++ b/tools/deadlock_example.txt @@ -340,6 +340,12 @@ optional arguments: Comma-separated list of unlock symbols to trace. Default is pthread_mutex_unlock. These symbols cannot be inlined in the binary. + -t THREADS, --threads THREADS + Specifies the maximum number of threads to trace. + default 65536. Note. 40 bytes per thread. + -e EDGES, --edges EDGES + Specifies the maximum number of edge cases that can be + recorded. default 65536. Note. 88 bytes per edge case. Examples: deadlock 181 # Analyze PID 181 -- 2.34.1