(binary_path, cwd, pid, core_pattern=None)
| 22 | |
| 23 | |
| 24 | def recover_core_dump_file(binary_path, cwd, pid, core_pattern=None): |
| 25 | class CoreFilePattern(object): |
| 26 | def __init__(self, path, mask): |
| 27 | self.path = path |
| 28 | self.mask = mask |
| 29 | |
| 30 | cwd = cwd or os.getcwd() |
| 31 | system = platform.system().lower() |
| 32 | if system.startswith("linux"): |
| 33 | import stat |
| 34 | import resource |
| 35 | |
| 36 | logger.debug("hostname = '%s'", socket.gethostname()) |
| 37 | logger.debug("rlimit_core = '%s'", str(resource.getrlimit(resource.RLIMIT_CORE))) |
| 38 | if core_pattern is None: |
| 39 | core_pattern = _read_file("/proc/sys/kernel/core_pattern") |
| 40 | logger.debug("core_pattern = '%s'", core_pattern) |
| 41 | if core_pattern.startswith("/"): |
| 42 | default_pattern = CoreFilePattern(os.path.dirname(core_pattern), '*') |
| 43 | else: |
| 44 | default_pattern = CoreFilePattern(cwd, '*') |
| 45 | |
| 46 | def resolve_core_mask(core_mask): |
| 47 | def resolve(text): |
| 48 | if text == "%p": |
| 49 | return str(pid) |
| 50 | elif text == "%e": |
| 51 | # https://github.com/torvalds/linux/blob/7876320f88802b22d4e2daf7eb027dd14175a0f8/include/linux/sched.h#L847 |
| 52 | # https://github.com/torvalds/linux/blob/7876320f88802b22d4e2daf7eb027dd14175a0f8/fs/coredump.c#L278 |
| 53 | return os.path.basename(binary_path)[:15] |
| 54 | elif text == "%E": |
| 55 | return binary_path.replace("/", "!") |
| 56 | elif text == "%%": |
| 57 | return "%" |
| 58 | elif text.startswith("%"): |
| 59 | return "*" |
| 60 | return text |
| 61 | |
| 62 | parts = filter(None, re.split(r"(%.)", core_mask)) |
| 63 | return "".join([resolve(p) for p in parts]) |
| 64 | |
| 65 | # don't interpret a program for piping core dumps as a pattern |
| 66 | if core_pattern and not core_pattern.startswith("|"): |
| 67 | default_pattern.mask = os.path.basename(core_pattern) |
| 68 | else: |
| 69 | default_pattern.mask = "core" |
| 70 | |
| 71 | core_uses_pid = int(_read_file("/proc/sys/kernel/core_uses_pid")) |
| 72 | logger.debug("core_uses_pid = '%d'", core_uses_pid) |
| 73 | if core_uses_pid == 1 and "%p" not in re.split(r"(%.)", default_pattern.mask): |
| 74 | default_pattern.mask += ".%p" |
| 75 | |
| 76 | # widely distributed core dump dir and mask (see DEVTOOLS-4408) |
| 77 | yandex_pattern = CoreFilePattern('/coredumps', '%e.%p.%s') |
| 78 | yandex_market_pattern = CoreFilePattern('/var/tmp/cores', 'core.%..%e.%s.%p.*') |
| 79 | |
| 80 | for pattern in [default_pattern, yandex_pattern, yandex_market_pattern]: |
| 81 | pattern.mask = resolve_core_mask(pattern.mask) |
nothing calls this directly
no test coverage detected