From 5f94e09f9c3f4887d7183c8c123213e94e6ede31 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 1 Sep 2023 14:09:17 -0700 Subject: [PATCH] libsysprof: avoid duplicate process records We want the first process record, but subsequent records should be ignored, except that we want to take the appropriate comm[] action from them. --- .../sysprof-document-process-private.h | 1 + src/libsysprof/sysprof-document-process.c | 18 +++++++++++++++++- src/libsysprof/sysprof-document.c | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/libsysprof/sysprof-document-process-private.h b/src/libsysprof/sysprof-document-process-private.h index e345e15a..78eb5f2d 100644 --- a/src/libsysprof/sysprof-document-process-private.h +++ b/src/libsysprof/sysprof-document-process-private.h @@ -28,5 +28,6 @@ G_BEGIN_DECLS SysprofProcessInfo *_sysprof_document_process_get_info (SysprofDocumentProcess *self); void _sysprof_document_process_set_info (SysprofDocumentProcess *self, SysprofProcessInfo *process_info); +const char *_sysprof_document_process_get_comm (SysprofDocumentProcess *self); G_END_DECLS diff --git a/src/libsysprof/sysprof-document-process.c b/src/libsysprof/sysprof-document-process.c index ca348983..0e0108b8 100644 --- a/src/libsysprof/sysprof-document-process.c +++ b/src/libsysprof/sysprof-document-process.c @@ -25,6 +25,7 @@ #include "sysprof-document-frame-private.h" #include "sysprof-document-process-private.h" #include "sysprof-mount.h" +#include "sysprof-symbol-private.h" #include "sysprof-thread-info.h" struct _SysprofDocumentProcess @@ -159,7 +160,7 @@ sysprof_document_process_init (SysprofDocumentProcess *self) } const char * -sysprof_document_process_get_command_line (SysprofDocumentProcess *self) +_sysprof_document_process_get_comm (SysprofDocumentProcess *self) { const SysprofCaptureProcess *proc; @@ -170,6 +171,21 @@ sysprof_document_process_get_command_line (SysprofDocumentProcess *self) return SYSPROF_DOCUMENT_FRAME_CSTRING (self, proc->cmdline); } +const char * +sysprof_document_process_get_command_line (SysprofDocumentProcess *self) +{ + g_return_val_if_fail (SYSPROF_IS_DOCUMENT_PROCESS (self), 0); + + /* Prefer ProcessInfo symbol name which gets updated from + * subsequent comm[] updates for process records. + */ + if (self->process_info != NULL && + self->process_info->symbol != NULL) + return self->process_info->symbol->name; + + return _sysprof_document_process_get_comm (self); +} + /** * sysprof_document_process_list_memory_maps: * @self: a #SysprofDocumentProcess diff --git a/src/libsysprof/sysprof-document.c b/src/libsysprof/sysprof-document.c index a147071c..61d01ada 100644 --- a/src/libsysprof/sysprof-document.c +++ b/src/libsysprof/sysprof-document.c @@ -803,11 +803,16 @@ static void sysprof_document_load_processes (SysprofDocument *self) { G_GNUC_UNUSED SysprofProcessInfo *pid0; + g_autoptr(GHashTable) seen = NULL; + g_autoptr(EggBitset) duplicate = NULL; EggBitsetIter iter; guint i; g_assert (SYSPROF_IS_DOCUMENT (self)); + seen = g_hash_table_new (NULL, NULL); + duplicate = egg_bitset_new_empty (); + /* Always create PID 0 info */ pid0 = _sysprof_document_process_info (self, 0, TRUE); @@ -818,7 +823,7 @@ sysprof_document_load_processes (SysprofDocument *self) g_autoptr(SysprofDocumentProcess) process = g_list_model_get_item (G_LIST_MODEL (self), i); int pid = sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (process)); SysprofProcessInfo *process_info = _sysprof_document_process_info (self, pid, TRUE); - const char *cmdline = sysprof_document_process_get_command_line (process); + const char *cmdline = _sysprof_document_process_get_comm (process); if (cmdline != NULL) { @@ -836,9 +841,19 @@ sysprof_document_load_processes (SysprofDocument *self) NULL, NULL, 0, 0, SYSPROF_SYMBOL_KIND_PROCESS); } + + /* Only include the first process discover for this process, + * ignore all secondary notations which are just comm[] updates. + */ + if (g_hash_table_contains (seen, GINT_TO_POINTER (pid))) + egg_bitset_add (duplicate, i); + else + g_hash_table_add (seen, GINT_TO_POINTER (pid)); } while (egg_bitset_iter_next (&iter, &i)); } + + egg_bitset_subtract (self->processes, duplicate); } static void