mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 15:10:53 +00:00
libsysprof-analyze: add SysprofProcessInfo
This internal type is used to collect things about a process like the memory maps, address layout, and symbol cache. This can persist once parsed at startup, then applied to objects created on demand such as the SysprofDocumentProcess or used by symbolizers internally rather than complicated function arguments.
This commit is contained in:
@ -29,6 +29,7 @@ libsysprof_analyze_private_sources = [
|
|||||||
'sysprof-mount.c',
|
'sysprof-mount.c',
|
||||||
'sysprof-mount-device.c',
|
'sysprof-mount-device.c',
|
||||||
'sysprof-mount-namespace.c',
|
'sysprof-mount-namespace.c',
|
||||||
|
'sysprof-process-info.c',
|
||||||
'sysprof-strings.c',
|
'sysprof-strings.c',
|
||||||
'sysprof-symbol-cache.c',
|
'sysprof-symbol-cache.c',
|
||||||
]
|
]
|
||||||
|
|||||||
@ -169,11 +169,9 @@ search_for_symbol_cb (gconstpointer a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SysprofSymbol *
|
static SysprofSymbol *
|
||||||
sysprof_bundled_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
sysprof_bundled_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||||
SysprofMountNamespace *mount_namespace,
|
const SysprofProcessInfo *process_info,
|
||||||
SysprofAddressLayout *address_layout,
|
SysprofAddress address)
|
||||||
int pid,
|
|
||||||
SysprofAddress address)
|
|
||||||
{
|
{
|
||||||
SysprofBundledSymbolizer *self = SYSPROF_BUNDLED_SYMBOLIZER (symbolizer);
|
SysprofBundledSymbolizer *self = SYSPROF_BUNDLED_SYMBOLIZER (symbolizer);
|
||||||
g_autoptr(GRefString) tag = NULL;
|
g_autoptr(GRefString) tag = NULL;
|
||||||
@ -181,7 +179,7 @@ sysprof_bundled_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
|||||||
const Decoded key = {
|
const Decoded key = {
|
||||||
.addr_begin = address,
|
.addr_begin = address,
|
||||||
.addr_end = address,
|
.addr_end = address,
|
||||||
.pid = pid,
|
.pid = process_info->pid,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.tag_offset = 0,
|
.tag_offset = 0,
|
||||||
};
|
};
|
||||||
|
|||||||
31
src/libsysprof-analyze/sysprof-document-process-private.h
Normal file
31
src/libsysprof-analyze/sysprof-document-process-private.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* sysprof-document-process-private.h
|
||||||
|
*
|
||||||
|
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sysprof-document-process.h"
|
||||||
|
#include "sysprof-process-info-private.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void _sysprof_document_process_set_info (SysprofDocumentProcess *self,
|
||||||
|
SysprofProcessInfo *process_info);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
@ -21,11 +21,12 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "sysprof-document-frame-private.h"
|
#include "sysprof-document-frame-private.h"
|
||||||
#include "sysprof-document-process.h"
|
#include "sysprof-document-process-private.h"
|
||||||
|
|
||||||
struct _SysprofDocumentProcess
|
struct _SysprofDocumentProcess
|
||||||
{
|
{
|
||||||
SysprofDocumentFrame parent_instance;
|
SysprofDocumentFrame parent_instance;
|
||||||
|
SysprofProcessInfo *process_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _SysprofDocumentProcessClass
|
struct _SysprofDocumentProcessClass
|
||||||
@ -43,6 +44,16 @@ G_DEFINE_FINAL_TYPE (SysprofDocumentProcess, sysprof_document_process, SYSPROF_T
|
|||||||
|
|
||||||
static GParamSpec *properties [N_PROPS];
|
static GParamSpec *properties [N_PROPS];
|
||||||
|
|
||||||
|
static void
|
||||||
|
sysprof_document_process_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
SysprofDocumentProcess *self = (SysprofDocumentProcess *)object;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->process_info, sysprof_process_info_unref);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (sysprof_document_process_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_document_process_get_property (GObject *object,
|
sysprof_document_process_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -67,6 +78,7 @@ sysprof_document_process_class_init (SysprofDocumentProcessClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = sysprof_document_process_finalize;
|
||||||
object_class->get_property = sysprof_document_process_get_property;
|
object_class->get_property = sysprof_document_process_get_property;
|
||||||
|
|
||||||
properties [PROP_COMMAND_LINE] =
|
properties [PROP_COMMAND_LINE] =
|
||||||
@ -93,3 +105,14 @@ sysprof_document_process_get_command_line (SysprofDocumentProcess *self)
|
|||||||
|
|
||||||
return SYSPROF_DOCUMENT_FRAME_CSTRING (self, proc->cmdline);
|
return SYSPROF_DOCUMENT_FRAME_CSTRING (self, proc->cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_sysprof_document_process_set_info (SysprofDocumentProcess *self,
|
||||||
|
SysprofProcessInfo *process_info)
|
||||||
|
{
|
||||||
|
g_return_if_fail (SYSPROF_IS_DOCUMENT_PROCESS (self));
|
||||||
|
g_return_if_fail (process_info != NULL);
|
||||||
|
g_return_if_fail (self->process_info == NULL);
|
||||||
|
|
||||||
|
self->process_info = sysprof_process_info_ref (process_info);
|
||||||
|
}
|
||||||
|
|||||||
@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
#include "sysprof-document.h"
|
#include "sysprof-document.h"
|
||||||
#include "sysprof-document-symbols.h"
|
#include "sysprof-document-symbols.h"
|
||||||
|
#include "sysprof-process-info-private.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
void _sysprof_document_symbols_new (SysprofDocument *document,
|
void _sysprof_document_symbols_new (SysprofDocument *document,
|
||||||
SysprofSymbolizer *symbolizer,
|
SysprofSymbolizer *symbolizer,
|
||||||
GHashTable *pid_to_mount_namespaces,
|
GHashTable *pid_to_process_info,
|
||||||
GHashTable *pid_to_address_layouts,
|
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|||||||
@ -31,9 +31,8 @@
|
|||||||
|
|
||||||
struct _SysprofDocumentSymbols
|
struct _SysprofDocumentSymbols
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
SysprofSymbol *context_switches[SYSPROF_ADDRESS_CONTEXT_GUEST_USER+1];
|
SysprofSymbol *context_switches[SYSPROF_ADDRESS_CONTEXT_GUEST_USER+1];
|
||||||
GHashTable *pid_to_symbol_cache;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_FINAL_TYPE (SysprofDocumentSymbols, sysprof_document_symbols, G_TYPE_OBJECT)
|
G_DEFINE_FINAL_TYPE (SysprofDocumentSymbols, sysprof_document_symbols, G_TYPE_OBJECT)
|
||||||
@ -46,8 +45,6 @@ sysprof_document_symbols_finalize (GObject *object)
|
|||||||
for (guint i = 0; i < G_N_ELEMENTS (self->context_switches); i++)
|
for (guint i = 0; i < G_N_ELEMENTS (self->context_switches); i++)
|
||||||
g_clear_object (&self->context_switches[i]);
|
g_clear_object (&self->context_switches[i]);
|
||||||
|
|
||||||
g_clear_pointer (&self->pid_to_symbol_cache, g_hash_table_unref);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (sysprof_document_symbols_parent_class)->finalize (object);
|
G_OBJECT_CLASS (sysprof_document_symbols_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +59,6 @@ sysprof_document_symbols_class_init (SysprofDocumentSymbolsClass *klass)
|
|||||||
static void
|
static void
|
||||||
sysprof_document_symbols_init (SysprofDocumentSymbols *self)
|
sysprof_document_symbols_init (SysprofDocumentSymbols *self)
|
||||||
{
|
{
|
||||||
self->pid_to_symbol_cache = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _Symbolize
|
typedef struct _Symbolize
|
||||||
@ -70,8 +66,7 @@ typedef struct _Symbolize
|
|||||||
SysprofDocument *document;
|
SysprofDocument *document;
|
||||||
SysprofSymbolizer *symbolizer;
|
SysprofSymbolizer *symbolizer;
|
||||||
SysprofDocumentSymbols *symbols;
|
SysprofDocumentSymbols *symbols;
|
||||||
GHashTable *pid_to_address_layouts;
|
GHashTable *pid_to_process_info;
|
||||||
GHashTable *pid_to_mount_namespaces;
|
|
||||||
} Symbolize;
|
} Symbolize;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -80,18 +75,15 @@ symbolize_free (Symbolize *state)
|
|||||||
g_clear_object (&state->document);
|
g_clear_object (&state->document);
|
||||||
g_clear_object (&state->symbolizer);
|
g_clear_object (&state->symbolizer);
|
||||||
g_clear_object (&state->symbols);
|
g_clear_object (&state->symbols);
|
||||||
g_clear_pointer (&state->pid_to_address_layouts, g_hash_table_unref);
|
g_clear_pointer (&state->pid_to_process_info, g_hash_table_unref);
|
||||||
g_clear_pointer (&state->pid_to_mount_namespaces, g_hash_table_unref);
|
|
||||||
g_free (state);
|
g_free (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_document_symbols_add_traceable (SysprofDocumentSymbols *self,
|
sysprof_document_symbols_add_traceable (SysprofDocumentSymbols *self,
|
||||||
|
SysprofProcessInfo *process_info,
|
||||||
SysprofDocumentTraceable *traceable,
|
SysprofDocumentTraceable *traceable,
|
||||||
SysprofSymbolizer *symbolizer,
|
SysprofSymbolizer *symbolizer)
|
||||||
SysprofMountNamespace *mount_namespace,
|
|
||||||
SysprofAddressLayout *address_layout,
|
|
||||||
SysprofSymbolCache *symbol_cache)
|
|
||||||
{
|
{
|
||||||
SysprofAddressContext last_context;
|
SysprofAddressContext last_context;
|
||||||
guint64 *addresses;
|
guint64 *addresses;
|
||||||
@ -99,6 +91,7 @@ sysprof_document_symbols_add_traceable (SysprofDocumentSymbols *self,
|
|||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
g_assert (SYSPROF_IS_DOCUMENT_SYMBOLS (self));
|
g_assert (SYSPROF_IS_DOCUMENT_SYMBOLS (self));
|
||||||
|
g_assert (process_info != NULL);
|
||||||
g_assert (SYSPROF_IS_DOCUMENT_TRACEABLE (traceable));
|
g_assert (SYSPROF_IS_DOCUMENT_TRACEABLE (traceable));
|
||||||
g_assert (SYSPROF_IS_SYMBOLIZER (symbolizer));
|
g_assert (SYSPROF_IS_SYMBOLIZER (symbolizer));
|
||||||
|
|
||||||
@ -118,16 +111,16 @@ sysprof_document_symbols_add_traceable (SysprofDocumentSymbols *self,
|
|||||||
{
|
{
|
||||||
last_context = context;
|
last_context = context;
|
||||||
}
|
}
|
||||||
else if (sysprof_symbol_cache_lookup (symbol_cache, address) != NULL)
|
else if (sysprof_symbol_cache_lookup (process_info->symbol_cache, address) != NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_autoptr(SysprofSymbol) symbol = _sysprof_symbolizer_symbolize (symbolizer, mount_namespace, address_layout, pid, address);
|
g_autoptr(SysprofSymbol) symbol = _sysprof_symbolizer_symbolize (symbolizer, process_info, address);
|
||||||
|
|
||||||
if (symbol != NULL)
|
if (symbol != NULL)
|
||||||
sysprof_symbol_cache_take (symbol_cache, g_steal_pointer (&symbol));
|
sysprof_symbol_cache_take (process_info->symbol_cache, g_steal_pointer (&symbol));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,19 +180,17 @@ sysprof_document_symbols_worker (GTask *task,
|
|||||||
{
|
{
|
||||||
g_autoptr(SysprofDocumentTraceable) traceable = g_list_model_get_item (model, i);
|
g_autoptr(SysprofDocumentTraceable) traceable = g_list_model_get_item (model, i);
|
||||||
int pid = sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (traceable));
|
int pid = sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (traceable));
|
||||||
SysprofMountNamespace *mount_namespace = g_hash_table_lookup (state->pid_to_mount_namespaces, GINT_TO_POINTER (pid));
|
SysprofProcessInfo *process_info = g_hash_table_lookup (state->pid_to_process_info, GINT_TO_POINTER (pid));
|
||||||
SysprofAddressLayout *address_layout = g_hash_table_lookup (state->pid_to_address_layouts, GINT_TO_POINTER (pid));
|
|
||||||
SysprofSymbolCache *symbol_cache = g_hash_table_lookup (state->symbols->pid_to_symbol_cache, GINT_TO_POINTER (pid));
|
|
||||||
|
|
||||||
if (symbol_cache == NULL)
|
/* We might hit this if we have "Process 0" which may be useful to
|
||||||
{
|
* let users know can take processing time. For now, that will just
|
||||||
symbol_cache = sysprof_symbol_cache_new ();
|
* get skipped unless we deem it really valuable (you'll just jump
|
||||||
g_hash_table_insert (state->symbols->pid_to_symbol_cache,
|
* to "- - Kernel - -" anyway.
|
||||||
GINT_TO_POINTER (pid),
|
*/
|
||||||
symbol_cache);
|
if (process_info == NULL)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
sysprof_document_symbols_add_traceable (state->symbols, traceable, state->symbolizer, mount_namespace, address_layout, symbol_cache);
|
sysprof_document_symbols_add_traceable (state->symbols, process_info, traceable, state->symbolizer);
|
||||||
}
|
}
|
||||||
while (gtk_bitset_iter_next (&iter, &i));
|
while (gtk_bitset_iter_next (&iter, &i));
|
||||||
}
|
}
|
||||||
@ -212,8 +203,7 @@ sysprof_document_symbols_worker (GTask *task,
|
|||||||
void
|
void
|
||||||
_sysprof_document_symbols_new (SysprofDocument *document,
|
_sysprof_document_symbols_new (SysprofDocument *document,
|
||||||
SysprofSymbolizer *symbolizer,
|
SysprofSymbolizer *symbolizer,
|
||||||
GHashTable *pid_to_mount_namespaces,
|
GHashTable *pid_to_process_info,
|
||||||
GHashTable *pid_to_address_layouts,
|
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
@ -228,8 +218,7 @@ _sysprof_document_symbols_new (SysprofDocument *document,
|
|||||||
state->document = g_object_ref (document);
|
state->document = g_object_ref (document);
|
||||||
state->symbolizer = g_object_ref (symbolizer);
|
state->symbolizer = g_object_ref (symbolizer);
|
||||||
state->symbols = g_object_new (SYSPROF_TYPE_DOCUMENT_SYMBOLS, NULL);
|
state->symbols = g_object_new (SYSPROF_TYPE_DOCUMENT_SYMBOLS, NULL);
|
||||||
state->pid_to_address_layouts = g_hash_table_ref (pid_to_address_layouts);
|
state->pid_to_process_info = g_hash_table_ref (pid_to_process_info);
|
||||||
state->pid_to_mount_namespaces = g_hash_table_ref (pid_to_mount_namespaces);
|
|
||||||
|
|
||||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||||
g_task_set_source_tag (task, _sysprof_document_symbols_new);
|
g_task_set_source_tag (task, _sysprof_document_symbols_new);
|
||||||
|
|||||||
@ -31,10 +31,12 @@
|
|||||||
#include "sysprof-document-file-private.h"
|
#include "sysprof-document-file-private.h"
|
||||||
#include "sysprof-document-frame-private.h"
|
#include "sysprof-document-frame-private.h"
|
||||||
#include "sysprof-document-mmap.h"
|
#include "sysprof-document-mmap.h"
|
||||||
|
#include "sysprof-document-process-private.h"
|
||||||
#include "sysprof-document-symbols-private.h"
|
#include "sysprof-document-symbols-private.h"
|
||||||
#include "sysprof-mount-private.h"
|
#include "sysprof-mount-private.h"
|
||||||
#include "sysprof-mount-device-private.h"
|
#include "sysprof-mount-device-private.h"
|
||||||
#include "sysprof-mount-namespace-private.h"
|
#include "sysprof-mount-namespace-private.h"
|
||||||
|
#include "sysprof-process-info-private.h"
|
||||||
#include "sysprof-strings-private.h"
|
#include "sysprof-strings-private.h"
|
||||||
#include "sysprof-symbolizer-private.h"
|
#include "sysprof-symbolizer-private.h"
|
||||||
|
|
||||||
@ -56,8 +58,7 @@ struct _SysprofDocument
|
|||||||
GtkBitset *mmaps;
|
GtkBitset *mmaps;
|
||||||
|
|
||||||
GHashTable *files_first_position;
|
GHashTable *files_first_position;
|
||||||
GHashTable *pid_to_address_layouts;
|
GHashTable *pid_to_process_info;
|
||||||
GHashTable *pid_to_mount_namespaces;
|
|
||||||
|
|
||||||
SysprofMountNamespace *mount_namespace;
|
SysprofMountNamespace *mount_namespace;
|
||||||
|
|
||||||
@ -89,16 +90,28 @@ sysprof_document_get_item (GListModel *model,
|
|||||||
{
|
{
|
||||||
SysprofDocument *self = SYSPROF_DOCUMENT (model);
|
SysprofDocument *self = SYSPROF_DOCUMENT (model);
|
||||||
SysprofDocumentFramePointer *ptr;
|
SysprofDocumentFramePointer *ptr;
|
||||||
|
SysprofDocumentFrame *ret;
|
||||||
|
|
||||||
if (position >= self->frames->len)
|
if (position >= self->frames->len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ptr = &g_array_index (self->frames, SysprofDocumentFramePointer, position);
|
ptr = &g_array_index (self->frames, SysprofDocumentFramePointer, position);
|
||||||
|
ret = _sysprof_document_frame_new (self->mapped_file,
|
||||||
|
(gconstpointer)&self->base[ptr->offset],
|
||||||
|
ptr->length,
|
||||||
|
self->needs_swap);
|
||||||
|
|
||||||
return _sysprof_document_frame_new (self->mapped_file,
|
/* Annotate processes with pre-calculated info */
|
||||||
(gconstpointer)&self->base[ptr->offset],
|
if (SYSPROF_IS_DOCUMENT_PROCESS (ret))
|
||||||
ptr->length,
|
{
|
||||||
self->needs_swap);
|
int pid = sysprof_document_frame_get_pid (ret);
|
||||||
|
SysprofProcessInfo *process_info = g_hash_table_lookup (self->pid_to_process_info, GINT_TO_POINTER (pid));
|
||||||
|
|
||||||
|
if (process_info != NULL)
|
||||||
|
_sysprof_document_process_set_info (SYSPROF_DOCUMENT_PROCESS (ret), process_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -120,6 +133,26 @@ _sysprof_document_traceables (SysprofDocument *self)
|
|||||||
return self->traceables;
|
return self->traceables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SysprofProcessInfo *
|
||||||
|
_sysprof_document_process_info (SysprofDocument *self,
|
||||||
|
int pid,
|
||||||
|
gboolean may_create)
|
||||||
|
{
|
||||||
|
SysprofProcessInfo *process_info;
|
||||||
|
|
||||||
|
g_return_val_if_fail (SYSPROF_IS_DOCUMENT (self), NULL);
|
||||||
|
|
||||||
|
process_info = g_hash_table_lookup (self->pid_to_process_info, GINT_TO_POINTER (pid));
|
||||||
|
|
||||||
|
if (process_info == NULL && may_create)
|
||||||
|
{
|
||||||
|
process_info = sysprof_process_info_new (sysprof_mount_namespace_copy (self->mount_namespace), pid);
|
||||||
|
g_hash_table_insert (self->pid_to_process_info, GINT_TO_POINTER (pid), process_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return process_info;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
decode_space (gchar **str)
|
decode_space (gchar **str)
|
||||||
{
|
{
|
||||||
@ -152,8 +185,7 @@ sysprof_document_finalize (GObject *object)
|
|||||||
|
|
||||||
g_clear_pointer (&self->strings, sysprof_strings_unref);
|
g_clear_pointer (&self->strings, sysprof_strings_unref);
|
||||||
|
|
||||||
g_clear_pointer (&self->pid_to_address_layouts, g_hash_table_unref);
|
g_clear_pointer (&self->pid_to_process_info, g_hash_table_unref);
|
||||||
g_clear_pointer (&self->pid_to_mount_namespaces, g_hash_table_unref);
|
|
||||||
g_clear_pointer (&self->mapped_file, g_mapped_file_unref);
|
g_clear_pointer (&self->mapped_file, g_mapped_file_unref);
|
||||||
g_clear_pointer (&self->frames, g_array_unref);
|
g_clear_pointer (&self->frames, g_array_unref);
|
||||||
|
|
||||||
@ -189,8 +221,7 @@ sysprof_document_init (SysprofDocument *self)
|
|||||||
self->mmaps = gtk_bitset_new_empty ();
|
self->mmaps = gtk_bitset_new_empty ();
|
||||||
|
|
||||||
self->files_first_position = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
self->files_first_position = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
self->pid_to_address_layouts = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
self->pid_to_process_info = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)sysprof_process_info_unref);
|
||||||
self->pid_to_mount_namespaces = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
|
||||||
|
|
||||||
self->mount_namespace = sysprof_mount_namespace_new ();
|
self->mount_namespace = sysprof_mount_namespace_new ();
|
||||||
}
|
}
|
||||||
@ -209,15 +240,9 @@ sysprof_document_load_memory_maps (SysprofDocument *self)
|
|||||||
{
|
{
|
||||||
g_autoptr(SysprofDocumentMmap) map = sysprof_document_get_item ((GListModel *)self, i);
|
g_autoptr(SysprofDocumentMmap) map = sysprof_document_get_item ((GListModel *)self, i);
|
||||||
int pid = sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (map));
|
int pid = sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (map));
|
||||||
SysprofAddressLayout *address_layout = g_hash_table_lookup (self->pid_to_address_layouts, GINT_TO_POINTER (pid));
|
SysprofProcessInfo *process_info = _sysprof_document_process_info (self, pid, TRUE);
|
||||||
|
|
||||||
if G_UNLIKELY (address_layout == NULL)
|
sysprof_address_layout_take (process_info->address_layout, g_steal_pointer (&map));
|
||||||
{
|
|
||||||
address_layout = sysprof_address_layout_new ();
|
|
||||||
g_hash_table_insert (self->pid_to_address_layouts, GINT_TO_POINTER (pid), address_layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
sysprof_address_layout_take (address_layout, g_steal_pointer (&map));
|
|
||||||
}
|
}
|
||||||
while (gtk_bitset_iter_next (&iter, &i));
|
while (gtk_bitset_iter_next (&iter, &i));
|
||||||
}
|
}
|
||||||
@ -304,7 +329,7 @@ sysprof_document_load_mountinfo (SysprofDocument *self,
|
|||||||
int pid,
|
int pid,
|
||||||
GBytes *bytes)
|
GBytes *bytes)
|
||||||
{
|
{
|
||||||
g_autoptr(SysprofMountNamespace) mount_namespace = NULL;
|
SysprofProcessInfo *process_info;
|
||||||
const char *contents;
|
const char *contents;
|
||||||
LineReader reader;
|
LineReader reader;
|
||||||
gsize contents_len;
|
gsize contents_len;
|
||||||
@ -319,7 +344,10 @@ sysprof_document_load_mountinfo (SysprofDocument *self,
|
|||||||
g_assert (contents != NULL);
|
g_assert (contents != NULL);
|
||||||
g_assert (contents[contents_len] == 0);
|
g_assert (contents[contents_len] == 0);
|
||||||
|
|
||||||
mount_namespace = sysprof_mount_namespace_copy (self->mount_namespace);
|
process_info = _sysprof_document_process_info (self, pid, FALSE);
|
||||||
|
|
||||||
|
g_assert (process_info != NULL);
|
||||||
|
g_assert (process_info->mount_namespace != NULL);
|
||||||
|
|
||||||
line_reader_init (&reader, (char *)contents, contents_len);
|
line_reader_init (&reader, (char *)contents, contents_len);
|
||||||
while ((line = line_reader_next (&reader, &line_len)))
|
while ((line = line_reader_next (&reader, &line_len)))
|
||||||
@ -329,12 +357,8 @@ sysprof_document_load_mountinfo (SysprofDocument *self,
|
|||||||
line[line_len] = 0;
|
line[line_len] = 0;
|
||||||
|
|
||||||
if ((mount = sysprof_mount_new_for_mountinfo (self->strings, line)))
|
if ((mount = sysprof_mount_new_for_mountinfo (self->strings, line)))
|
||||||
sysprof_mount_namespace_add_mount (mount_namespace, g_steal_pointer (&mount));
|
sysprof_mount_namespace_add_mount (process_info->mount_namespace, g_steal_pointer (&mount));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (self->pid_to_mount_namespaces,
|
|
||||||
GINT_TO_POINTER (pid),
|
|
||||||
g_steal_pointer (&mount_namespace));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -345,10 +369,9 @@ sysprof_document_load_mountinfos (SysprofDocument *self)
|
|||||||
|
|
||||||
g_assert (SYSPROF_IS_DOCUMENT (self));
|
g_assert (SYSPROF_IS_DOCUMENT (self));
|
||||||
|
|
||||||
g_hash_table_iter_init (&hiter, self->pid_to_address_layouts);
|
g_hash_table_iter_init (&hiter, self->pid_to_process_info);
|
||||||
while (g_hash_table_iter_next (&hiter, &key, &value))
|
while (g_hash_table_iter_next (&hiter, &key, &value))
|
||||||
{
|
{
|
||||||
g_autoptr(SysprofMountNamespace) mount_namespace = sysprof_mount_namespace_new ();
|
|
||||||
int pid = GPOINTER_TO_INT (key);
|
int pid = GPOINTER_TO_INT (key);
|
||||||
g_autofree char *path = g_strdup_printf ("/proc/%d/mountinfo", pid);
|
g_autofree char *path = g_strdup_printf ("/proc/%d/mountinfo", pid);
|
||||||
g_autoptr(SysprofDocumentFile) file = sysprof_document_lookup_file (self, path);
|
g_autoptr(SysprofDocumentFile) file = sysprof_document_lookup_file (self, path);
|
||||||
@ -565,15 +588,14 @@ sysprof_document_symbolize_prepare_cb (GObject *object,
|
|||||||
|
|
||||||
g_assert (self != NULL);
|
g_assert (self != NULL);
|
||||||
g_assert (SYSPROF_IS_DOCUMENT (self));
|
g_assert (SYSPROF_IS_DOCUMENT (self));
|
||||||
g_assert (self->pid_to_mount_namespaces != NULL);
|
g_assert (self->pid_to_process_info != NULL);
|
||||||
|
|
||||||
if (!_sysprof_symbolizer_prepare_finish (symbolizer, result, &error))
|
if (!_sysprof_symbolizer_prepare_finish (symbolizer, result, &error))
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
g_task_return_error (task, g_steal_pointer (&error));
|
||||||
else
|
else
|
||||||
_sysprof_document_symbols_new (g_task_get_source_object (task),
|
_sysprof_document_symbols_new (g_task_get_source_object (task),
|
||||||
symbolizer,
|
symbolizer,
|
||||||
self->pid_to_mount_namespaces,
|
self->pid_to_process_info,
|
||||||
self->pid_to_address_layouts,
|
|
||||||
g_task_get_cancellable (task),
|
g_task_get_cancellable (task),
|
||||||
sysprof_document_symbolize_symbols_cb,
|
sysprof_document_symbolize_symbols_cb,
|
||||||
g_object_ref (task));
|
g_object_ref (task));
|
||||||
|
|||||||
@ -118,18 +118,16 @@ sysprof_multi_symbolizer_prepare_finish (SysprofSymbolizer *symbolizer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SysprofSymbol *
|
static SysprofSymbol *
|
||||||
sysprof_multi_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
sysprof_multi_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||||
SysprofMountNamespace *mount_namespace,
|
const SysprofProcessInfo *process_info,
|
||||||
SysprofAddressLayout *address_layout,
|
SysprofAddress address)
|
||||||
int pid,
|
|
||||||
SysprofAddress address)
|
|
||||||
{
|
{
|
||||||
SysprofMultiSymbolizer *self = SYSPROF_MULTI_SYMBOLIZER (symbolizer);
|
SysprofMultiSymbolizer *self = SYSPROF_MULTI_SYMBOLIZER (symbolizer);
|
||||||
|
|
||||||
for (guint i = 0; i < self->symbolizers->len; i++)
|
for (guint i = 0; i < self->symbolizers->len; i++)
|
||||||
{
|
{
|
||||||
SysprofSymbolizer *child = g_ptr_array_index (self->symbolizers, i);
|
SysprofSymbolizer *child = g_ptr_array_index (self->symbolizers, i);
|
||||||
SysprofSymbol *symbol = _sysprof_symbolizer_symbolize (child, mount_namespace, address_layout, pid, address);
|
SysprofSymbol *symbol = _sysprof_symbolizer_symbolize (child, process_info, address);
|
||||||
|
|
||||||
if (symbol != NULL)
|
if (symbol != NULL)
|
||||||
return symbol;
|
return symbol;
|
||||||
|
|||||||
42
src/libsysprof-analyze/sysprof-process-info-private.h
Normal file
42
src/libsysprof-analyze/sysprof-process-info-private.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* sysprof-process-info-private.h
|
||||||
|
*
|
||||||
|
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sysprof-address-layout-private.h"
|
||||||
|
#include "sysprof-mount-namespace-private.h"
|
||||||
|
#include "sysprof-symbol-cache-private.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _SysprofProcessInfo
|
||||||
|
{
|
||||||
|
SysprofAddressLayout *address_layout;
|
||||||
|
SysprofMountNamespace *mount_namespace;
|
||||||
|
SysprofSymbolCache *symbol_cache;
|
||||||
|
int pid;
|
||||||
|
} SysprofProcessInfo;
|
||||||
|
|
||||||
|
SysprofProcessInfo *sysprof_process_info_new (SysprofMountNamespace *mount_namespace,
|
||||||
|
int pid);
|
||||||
|
SysprofProcessInfo *sysprof_process_info_ref (SysprofProcessInfo *self);
|
||||||
|
void sysprof_process_info_unref (SysprofProcessInfo *self);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
67
src/libsysprof-analyze/sysprof-process-info.c
Normal file
67
src/libsysprof-analyze/sysprof-process-info.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* sysprof-process-info.c
|
||||||
|
*
|
||||||
|
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "sysprof-process-info-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_BOXED_TYPE (SysprofProcessInfo,
|
||||||
|
sysprof_process_info,
|
||||||
|
sysprof_process_info_ref,
|
||||||
|
sysprof_process_info_unref)
|
||||||
|
|
||||||
|
SysprofProcessInfo *
|
||||||
|
sysprof_process_info_new (SysprofMountNamespace *mount_namespace,
|
||||||
|
int pid)
|
||||||
|
{
|
||||||
|
SysprofProcessInfo *self;
|
||||||
|
|
||||||
|
self = g_atomic_rc_box_new0 (SysprofProcessInfo);
|
||||||
|
self->pid = pid;
|
||||||
|
self->address_layout = sysprof_address_layout_new ();
|
||||||
|
self->symbol_cache = sysprof_symbol_cache_new ();
|
||||||
|
self->mount_namespace = mount_namespace;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
SysprofProcessInfo *
|
||||||
|
sysprof_process_info_ref (SysprofProcessInfo *self)
|
||||||
|
{
|
||||||
|
return g_atomic_rc_box_acquire (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sysprof_process_info_finalize (gpointer data)
|
||||||
|
{
|
||||||
|
SysprofProcessInfo *self = data;
|
||||||
|
|
||||||
|
g_clear_object (&self->address_layout);
|
||||||
|
g_clear_object (&self->symbol_cache);
|
||||||
|
g_clear_object (&self->mount_namespace);
|
||||||
|
|
||||||
|
self->pid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sysprof_process_info_unref (SysprofProcessInfo *self)
|
||||||
|
{
|
||||||
|
g_atomic_rc_box_release_full (self, sysprof_process_info_finalize);
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include "sysprof-symbol.h"
|
#include "sysprof-symbol.h"
|
||||||
#include "sysprof-symbolizer.h"
|
#include "sysprof-symbolizer.h"
|
||||||
#include "sysprof-mount-namespace-private.h"
|
#include "sysprof-mount-namespace-private.h"
|
||||||
|
#include "sysprof-process-info-private.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -39,34 +40,30 @@ struct _SysprofSymbolizerClass
|
|||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (*prepare_async) (SysprofSymbolizer *self,
|
void (*prepare_async) (SysprofSymbolizer *self,
|
||||||
SysprofDocument *document,
|
SysprofDocument *document,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
gboolean (*prepare_finish) (SysprofSymbolizer *self,
|
gboolean (*prepare_finish) (SysprofSymbolizer *self,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error);
|
GError **error);
|
||||||
SysprofSymbol *(*symbolize) (SysprofSymbolizer *self,
|
SysprofSymbol *(*symbolize) (SysprofSymbolizer *self,
|
||||||
SysprofMountNamespace *mount_namespace,
|
const SysprofProcessInfo *process_info,
|
||||||
SysprofAddressLayout *address_layout,
|
SysprofAddress address);
|
||||||
int pid,
|
|
||||||
SysprofAddress address);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void _sysprof_symbolizer_prepare_async (SysprofSymbolizer *self,
|
void _sysprof_symbolizer_prepare_async (SysprofSymbolizer *self,
|
||||||
SysprofDocument *document,
|
SysprofDocument *document,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
gboolean _sysprof_symbolizer_prepare_finish (SysprofSymbolizer *self,
|
gboolean _sysprof_symbolizer_prepare_finish (SysprofSymbolizer *self,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error);
|
GError **error);
|
||||||
SysprofSymbol *_sysprof_symbolizer_symbolize (SysprofSymbolizer *self,
|
SysprofSymbol *_sysprof_symbolizer_symbolize (SysprofSymbolizer *self,
|
||||||
SysprofMountNamespace *mount_namespace,
|
const SysprofProcessInfo *process_info,
|
||||||
SysprofAddressLayout *address_layout,
|
SysprofAddress address);
|
||||||
int pid,
|
|
||||||
SysprofAddress address);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -91,11 +91,9 @@ _sysprof_symbolizer_prepare_finish (SysprofSymbolizer *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SysprofSymbol *
|
SysprofSymbol *
|
||||||
_sysprof_symbolizer_symbolize (SysprofSymbolizer *self,
|
_sysprof_symbolizer_symbolize (SysprofSymbolizer *self,
|
||||||
SysprofMountNamespace *mount_namespace,
|
const SysprofProcessInfo *process_info,
|
||||||
SysprofAddressLayout *address_layout,
|
SysprofAddress address)
|
||||||
int pid,
|
|
||||||
SysprofAddress address)
|
|
||||||
{
|
{
|
||||||
return SYSPROF_SYMBOLIZER_GET_CLASS (self)->symbolize (self, mount_namespace, address_layout, pid, address);
|
return SYSPROF_SYMBOLIZER_GET_CLASS (self)->symbolize (self, process_info, address);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user