|
3 | 3 | import json
|
4 | 4 | import subprocess
|
5 | 5 | import argparse
|
| 6 | +import signal |
6 | 7 | import os
|
7 | 8 |
|
| 9 | + |
| 10 | +def signal_info(minidump_text): |
| 11 | + minidump_lines = minidump_text.splitlines() |
| 12 | + |
| 13 | + signal_name = "UNKNOWN" |
| 14 | + signal_str = "no description" |
| 15 | + for line in minidump_lines: |
| 16 | + line = line.strip() |
| 17 | + if line.startswith('Crash|'): |
| 18 | + # "Crash|SIGSEGV|0x452e|0" |
| 19 | + signal_name = line.split('|')[1] |
| 20 | + break |
| 21 | + |
| 22 | + try: |
| 23 | + signal_code = getattr(signal, signal_name) |
| 24 | + print(f"Signal name '{signal_name}' corresponds to signal number {signal_code}.") |
| 25 | + except AttributeError: |
| 26 | + print(f"Signal name '{signal_name}' is not a valid signal.") |
| 27 | + else: |
| 28 | + try: |
| 29 | + signal_str = signal.strsignal(signal_code) |
| 30 | + print(f"Signal code '{signal_code}' corresponds to signal description {signal_str}.") |
| 31 | + except ValueError: |
| 32 | + print(f"Signal code '{signal_code}' is not a valid value.") |
| 33 | + |
| 34 | + return "Program terminated with signal {}, {}.".format(signal_name, signal_str) |
| 35 | + |
| 36 | + |
8 | 37 | if __name__ == "__main__":
|
9 | 38 | parser = argparse.ArgumentParser(
|
10 | 39 | description="Minidump files processing"
|
|
21 | 50 | elf_cmd = ["readelf", "-n", "/opt/ydb/bin/ydbd"]
|
22 | 51 | svnrev_cmd = ["/opt/ydb/bin/ydbd", "--svnrevision"]
|
23 | 52 | mndmp_cmd = ["/usr/bin/minidump-2-core", "-v", dmp_file, "-o", core_file]
|
| 53 | + stwlk_cmd = ["/usr/bin/minidump_stackwalk", "-m", dmp_file] |
24 | 54 | gdb_cmd = [
|
25 | 55 | "/usr/bin/gdb",
|
26 | 56 | "-q",
|
27 | 57 | "-batch",
|
28 | 58 | "-iex=set auto-load safe-path /",
|
29 |
| - "-iex=set print thread-events off", |
30 |
| - "-ex=backtrace", |
31 | 59 | "-ex=thread apply all bt",
|
32 | 60 | "/opt/ydb/bin/ydbd",
|
33 | 61 | core_file,
|
34 | 62 | ]
|
35 | 63 |
|
36 | 64 | elf_resp = subprocess.check_output(elf_cmd).decode("utf-8")
|
37 | 65 | svnrev_resp = subprocess.check_output(svnrev_cmd).decode("utf-8")
|
38 |
| - subprocess.run(mndmp_cmd) |
39 |
| - gdb_resp = subprocess.check_output(gdb_cmd).decode("utf-8") |
| 66 | + |
| 67 | + subprocess.run(mndmp_cmd, stderr=subprocess.DEVNULL) |
| 68 | + stwlk_resp = subprocess.check_output(stwlk_cmd, stderr=subprocess.DEVNULL).decode("utf-8") |
| 69 | + gdb_resp = subprocess.check_output(gdb_cmd, stderr=subprocess.DEVNULL).decode("utf-8") |
| 70 | + stacktrace = [] |
| 71 | + for line in gdb_resp.splitlines(): |
| 72 | + stacktrace.append(line) |
| 73 | + if line.startswith("Core was generated"): |
| 74 | + stacktrace.append(signal_info(stwlk_resp)) |
| 75 | + stacktrace_str = '\n'.join(stacktrace) |
| 76 | + |
40 | 77 | os.remove(dmp_file)
|
41 | 78 | os.remove(core_file)
|
42 | 79 |
|
43 |
| - ret = json.dumps({"binary": "/opt/ydb/bin/ydbd", "readelf": elf_resp, "svnrevision": svnrev_resp, "stacktrace": gdb_resp}) |
| 80 | + ret = json.dumps({"binary": "/opt/ydb/bin/ydbd", "readelf": elf_resp, "svnrevision": svnrev_resp, "stacktrace": stacktrace_str}) |
44 | 81 | with open(json_file,"w") as out:
|
45 | 82 | out.write(ret)
|
0 commit comments