diff --git a/granulate_utils/golang.py b/granulate_utils/golang.py index 2c9157ca..9cd33966 100644 --- a/granulate_utils/golang.py +++ b/granulate_utils/golang.py @@ -7,10 +7,11 @@ import struct from typing import Optional -from psutil import NoSuchProcess, Process +from psutil import NoSuchProcess, Process, pids from granulate_utils.linux.elf import read_elf_symbol, read_elf_va -from granulate_utils.linux.process import is_kernel_thread +from granulate_utils.linux.ns import get_mnt_ns_ancestor +from granulate_utils.linux.process import is_kernel_thread, process_exe def is_golang_process(process: Process) -> bool: @@ -19,14 +20,29 @@ def is_golang_process(process: Process) -> bool: @functools.lru_cache(maxsize=4096) def get_process_golang_version(process: Process) -> Optional[str]: - elf_path = f"/proc/{process.pid}/exe" + try: + exe = process_exe(process) + except: + return None + elf_path = f"/proc/{get_mnt_ns_ancestor(process).pid}/root{exe}" + return get_version_hidden_in_exe(elf_path, process.create_time()) + + + +@functools.lru_cache(maxsize=4096) +def get_version_hidden_in_exe(elf_path: str, process_start_time: float) -> Optional[str]: + process = None + for pid in pids(): + if Process(pid).create_time() == process_start_time: + process = Process(pid) + if process is None: + raise NoSuchProcess(process) try: symbol_data = read_elf_symbol(elf_path, "runtime.buildVersion", 16) except FileNotFoundError: raise NoSuchProcess(process.pid) if symbol_data is None: return None - # Declaration of go string type: # type stringStruct struct { # str unsafe.Pointer