From e073a872fff4cae2e66dcf6c4eb9fe8c34853860 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Mon, 7 Aug 2023 00:01:06 +0300 Subject: [PATCH] Add ELF arch as app metadata --- gprofiler/metadata/application_metadata.py | 16 ++++++++++++++++ granulate-utils | 2 +- tests/test_app_metadata.py | 7 +++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gprofiler/metadata/application_metadata.py b/gprofiler/metadata/application_metadata.py index 355f5111c..95df11be5 100644 --- a/gprofiler/metadata/application_metadata.py +++ b/gprofiler/metadata/application_metadata.py @@ -7,6 +7,7 @@ from threading import Event, Lock from typing import Any, Dict, Optional +from granulate_utils.linux.elf import elf_arch_to_uname_arch, get_elf_arch from granulate_utils.linux.process import is_process_running, process_exe, read_process_execfn from psutil import NoSuchProcess, Process, ZombieProcess @@ -87,4 +88,19 @@ def make_application_metadata(self, process: Process) -> Dict[str, Any]: execfn = f"error: {e.__class__.__name__}" md["execfn"] = execfn + try: + # take arch from the executed elf, not the host system, because (although unlikely) it's possible + # that the process runs a different, emulated architecture. + arch = ( + "error: not supported on Windows" + if is_windows() + else elf_arch_to_uname_arch(get_elf_arch(f"/proc/{process.pid}/exe")) + ) + except (NoSuchProcess, ZombieProcess): + raise # let caller handle + except Exception as e: + logger.exception("Exception while getting process exe architecture", pid=process.pid) + arch = f"error: {e.__class__.__name__}" + md["arch"] = arch + return md diff --git a/granulate-utils b/granulate-utils index 3a10e901b..33029d049 160000 --- a/granulate-utils +++ b/granulate-utils @@ -1 +1 @@ -Subproject commit 3a10e901b289aeb589db7ff8aab56db3860cf52d +Subproject commit 33029d0499b790538e7c59b89eb38c8f582d34fd diff --git a/tests/test_app_metadata.py b/tests/test_app_metadata.py index 0da65c5ba..7186a804d 100644 --- a/tests/test_app_metadata.py +++ b/tests/test_app_metadata.py @@ -3,6 +3,7 @@ # Licensed under the AGPL3 License. See LICENSE.md in the project root for license information. # import json +import platform from pathlib import Path from typing import Dict, List @@ -34,6 +35,7 @@ else "buildid:a04b9016e15a247fbc21c91260c13e17a458ed33", "python_version": "Python 3.6.15", "sys_maxunicode": None, + "arch": platform.machine(), }, ), ( @@ -52,6 +54,7 @@ "ruby_version": "ruby 2.6.7p197 (2021-04-05 revision 67941) [aarch64-linux]" if is_aarch64() else "ruby 2.6.7p197 (2021-04-05 revision 67941) [x86_64-linux]", + "arch": platform.machine(), }, ), ( @@ -67,6 +70,7 @@ "libjvm_elfid": "buildid:33a1021cade63f16e30726be4111f20c34444764" if is_aarch64() else "buildid:622795512a2c037aec4d7ca6da05527dae86e460", + "arch": platform.machine(), "jvm_flags": [ { "name": "CICompilerCount", @@ -152,6 +156,7 @@ "link": "dynamic", "libc": "glibc", "stripped": False, + "arch": platform.machine(), }, ), ( @@ -164,6 +169,7 @@ "node_version": "v10.24.1", "link": "dynamic", "libc": "glibc", + "arch": platform.machine(), }, ), ( @@ -174,6 +180,7 @@ "dotnet_version": "6.0.302", "exe": "/usr/share/dotnet/dotnet", "execfn": "/usr/bin/dotnet", + "arch": platform.machine(), }, ), ],