This commit is contained in:
drindhauser
2019-12-18 12:05:14 +01:00
parent a046b142a9
commit 67a19e7520
4 changed files with 62 additions and 35 deletions

View File

@ -4,10 +4,16 @@ Coredump Uploader
Requirements: Requirements:
------- -------
python
GDB GDB
elfutils elfutils
sentry-sdk
click
Usage: Usage:
-------- --------

1
tests/coredumplib.py Symbolic link
View File

@ -0,0 +1 @@
../upload-coredump.py

View File

@ -24,7 +24,7 @@ def test_code_id_to_debug_id():
instruction_addr="0x000055ee7d69e60a", instruction_addr="0x000055ee7d69e60a",
name_of_function="crashing_function", name_of_function="crashing_function",
path="./test.c", path="./test.c",
lineno="3", lineno=3,
), ),
], ],
[ [
@ -33,7 +33,7 @@ def test_code_id_to_debug_id():
instruction_addr="0x000055ee7d69e61c", instruction_addr="0x000055ee7d69e61c",
name_of_function="main", name_of_function="main",
path="./test.c", path="./test.c",
lineno="7", lineno=7,
), ),
], ],
[ [
@ -46,10 +46,19 @@ def test_code_id_to_debug_id():
), ),
], ],
[ [
"3 0x000055708e742643 in main ()", "#1 0x0000748f47a34256 in <test::function as test::function>::event ()",
Frame( Frame(
instruction_addr="0x000055708e742643", instruction_addr="0x0000748f47a34256",
name_of_function="main", name_of_function="event",
path="abs_path",
lineno=None,
),
],
[
"#1 0x0000748f47a34256 in test::function as test::function::event ()",
Frame(
instruction_addr="0x0000748f47a34256",
name_of_function="event",
path="abs_path", path="abs_path",
lineno=None, lineno=None,
), ),
@ -81,7 +90,7 @@ def test_get_frame(gdb_output, parsed):
[ [
"0x55ee7d69e000+0x201018 b814d9f87debe4b312c06a03fa8d6b44a7b41199@0x55ee7d69e284 ./a.out . a.out", "0x55ee7d69e000+0x201018 b814d9f87debe4b312c06a03fa8d6b44a7b41199@0x55ee7d69e284 ./a.out . a.out",
Image( Image(
code_file="./a.out", code_file="/a.out",
code_id="b814d9f87debe4b312c06a03fa8d6b44a7b41199", code_id="b814d9f87debe4b312c06a03fa8d6b44a7b41199",
image_addr="0x55ee7d69e000", image_addr="0x55ee7d69e000",
image_size=2101272, image_size=2101272,
@ -112,9 +121,9 @@ def test_frame_to_json():
frame = Frame() frame = Frame()
assert frame.to_json() == { assert frame.to_json() == {
"instruction_addr": "", "instruction_addr": "",
"lineno": "", "lineno": None,
"name_of_function": "", "name_of_function": "",
"path": "", "path": "abs_path",
} }

View File

@ -10,7 +10,9 @@ import time
class Frame: class Frame:
def __init__(self, instruction_addr="", name_of_function="", path="", lineno=""): def __init__(
self, instruction_addr="", name_of_function="", path="abs_path", lineno=None,
):
self.instruction_addr = instruction_addr self.instruction_addr = instruction_addr
self.name_of_function = name_of_function self.name_of_function = name_of_function
self.path = path self.path = path
@ -58,7 +60,7 @@ _frame_re = re.compile(
)? )?
#path from the file #path from the file
(\s\(\))? (\sat\s)? (\s\(.*\))? (\sat\s)?
(?P<path> (?P<path>
.*\.c .*\.c
)? )?
@ -127,12 +129,15 @@ def get_frame(gdb_output):
return return
frame.instruction_addr = temp.group("instruction_addr") frame.instruction_addr = temp.group("instruction_addr")
frame.name_of_function = temp.group("name_of_function") frame.name_of_function = temp.group("name_of_function")
frame.lineno = temp.group("lineno")
if temp.group("path") is None: if temp.group("lineno") is not None:
frame.path = "abs_path" frame.lineno = int(temp.group("lineno"))
else:
if temp.group("path") is not None:
frame.path = temp.group("path") frame.path = temp.group("path")
return frame return frame
@ -167,10 +172,10 @@ def main(path_to_core, path_to_executable, sentry_dsn, gdb_path, elfutils_path):
if os.path.isfile(path_to_executable) is not True: if os.path.isfile(path_to_executable) is not True:
error("Wrong path to executable") error("Wrong path to executable")
if gdb_path is not None and os.path.isfile(gdb_path) is not True: if gdb_path is not None and os.path.exists(gdb_path) is not True:
error("Wrong path for gdb") error("Wrong path for gdb")
if elfutils_path is not None and os.path.isfile(elfutils_path) is not True: if elfutils_path is not None and os.path.exists(elfutils_path) is not True:
error("Wrong path for elfutils") error("Wrong path for elfutils")
image_list = [] image_list = []
@ -187,11 +192,14 @@ def main(path_to_core, path_to_executable, sentry_dsn, gdb_path, elfutils_path):
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
) )
else: else:
process = subprocess.Popen( try:
[gdb_path, "gdb", "-c", path_to_core, path_to_executable], process = subprocess.Popen(
stdout=subprocess.PIPE, [gdb_path, "gdb", "-c", path_to_core, path_to_executable],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
) stdin=subprocess.PIPE,
)
except OSError as err:
error(format(err))
output = re.search(r"#0.*", str(process.communicate(input="bt"))) output = re.search(r"#0.*", str(process.communicate(input="bt")))
try: try:
@ -206,24 +214,27 @@ def main(path_to_core, path_to_executable, sentry_dsn, gdb_path, elfutils_path):
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
) )
else: else:
process = subprocess.Popen( try:
[ process = subprocess.Popen(
elfutils_path, [
"eu-unstrip", elfutils_path,
"-n", "eu-unstrip",
"--core", "-n",
path_to_core, "--core",
"-e", path_to_core,
path_to_executable, "-e",
], path_to_executable,
stdout=subprocess.PIPE, ],
) stdout=subprocess.PIPE,
)
except OSError as err:
error(format(err))
output = process.communicate() output = process.communicate()
eu_unstrip_output = str(output[0]).split("\n") eu_unstrip_output = str(output[0]).split("\n")
for x in range(2, len(gdb_output)): for x in range(1, len(gdb_output)):
frame = get_frame(gdb_output[x]) frame = get_frame(gdb_output[x])
if frame is not None: if frame is not None:
frame_list.append(frame) frame_list.append(frame)
@ -246,7 +257,7 @@ def main(path_to_core, path_to_executable, sentry_dsn, gdb_path, elfutils_path):
sentry_sdk.init(sentry_dsn) sentry_sdk.init(sentry_dsn)
sentry_sdk.capture_event(data) sentry_sdk.capture_event(data)
print("Core dump sent to sentry") print("Core dump sent to sentry!")
if __name__ == "__main__": if __name__ == "__main__":