mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 23:20:54 +00:00
libsysprof: add simple text format for category rules
This commit is contained in:
64
src/libsysprof/categories.txt
Normal file
64
src/libsysprof/categories.txt
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
EGL:
|
||||||
|
egl* paint inherit
|
||||||
|
|
||||||
|
|
||||||
|
FontConfig:
|
||||||
|
* layout inherit
|
||||||
|
|
||||||
|
|
||||||
|
GL:
|
||||||
|
gl* paint inherit
|
||||||
|
|
||||||
|
|
||||||
|
GLib:
|
||||||
|
gtk_main_* main-loop
|
||||||
|
gtk_wakeup_* main-loop inherit
|
||||||
|
|
||||||
|
|
||||||
|
GTK 4:
|
||||||
|
gtk_widget_snapshot paint inherit
|
||||||
|
gtk_widget_real_snapshot paint inherit
|
||||||
|
gtk_widget_render paint inherit
|
||||||
|
gdk_snapshot_* paint inherit
|
||||||
|
gtk_snapshot_* paint inherit
|
||||||
|
gsk_* paint inherit
|
||||||
|
gdk_frame_clock_paint paint inherit
|
||||||
|
_gdk_frame_clock_emit_paint paint inherit
|
||||||
|
_gdk_frame_clock_emit_after_paint paint inherit
|
||||||
|
|
||||||
|
gtk_widget_measure layout inherit
|
||||||
|
gtk_css_* layout inherit
|
||||||
|
_gdk_frame_clock_emit_layout layout inherit
|
||||||
|
gtk_builder_* layout inherit
|
||||||
|
gtk_buildable_* layout inherit
|
||||||
|
|
||||||
|
gdk_surface_handle_event input inherit
|
||||||
|
gtk_im_* input inherit
|
||||||
|
do_update_im_spot_location input inherit
|
||||||
|
|
||||||
|
gtk_window_present* windowing inherit
|
||||||
|
|
||||||
|
gtk_accessible_* a11y inherit
|
||||||
|
gtk_at_* a11y inherit
|
||||||
|
|
||||||
|
|
||||||
|
Harfbuzz:
|
||||||
|
* layout inherit
|
||||||
|
|
||||||
|
|
||||||
|
libc:
|
||||||
|
poll main-loop inherit
|
||||||
|
select main-loop inherit
|
||||||
|
epoll main-loop inherit
|
||||||
|
|
||||||
|
|
||||||
|
Pango:
|
||||||
|
* layout inherit
|
||||||
|
|
||||||
|
|
||||||
|
Wayland Client:
|
||||||
|
wl_* windowing inherit
|
||||||
|
|
||||||
|
|
||||||
|
Wayland Server:
|
||||||
|
wl_* windowing inherit
|
||||||
6
src/libsysprof/libsysprof.gresource.xml
Normal file
6
src/libsysprof/libsysprof.gresource.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/org/gnome/libsysprof">
|
||||||
|
<file>categories.txt</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
||||||
@ -5,6 +5,7 @@ libsysprof_public_sources = [
|
|||||||
'sysprof-callgraph-symbol.c',
|
'sysprof-callgraph-symbol.c',
|
||||||
'sysprof-callgraph.c',
|
'sysprof-callgraph.c',
|
||||||
'sysprof-callgraph-categorize.c',
|
'sysprof-callgraph-categorize.c',
|
||||||
|
'sysprof-categories.c',
|
||||||
'sysprof-cpu-info.c',
|
'sysprof-cpu-info.c',
|
||||||
'sysprof-cpu-usage.c',
|
'sysprof-cpu-usage.c',
|
||||||
'sysprof-diagnostic.c',
|
'sysprof-diagnostic.c',
|
||||||
@ -157,6 +158,11 @@ libsysprof_enums = gnome.mkenums_simple('sysprof-enums',
|
|||||||
install_dir: sysprof_header_dir,
|
install_dir: sysprof_header_dir,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
libsysprof_resources = gnome.compile_resources('libsysprof-resources', 'libsysprof.gresource.xml',
|
||||||
|
source_dir: 'resources',
|
||||||
|
c_name: 'libsysprof',
|
||||||
|
)
|
||||||
|
|
||||||
libsysprof_deps = [
|
libsysprof_deps = [
|
||||||
dependency('gio-2.0', version: glib_req_version),
|
dependency('gio-2.0', version: glib_req_version),
|
||||||
dependency('gio-unix-2.0',
|
dependency('gio-unix-2.0',
|
||||||
@ -179,6 +185,7 @@ libsysprof_static = static_library(
|
|||||||
libsysprof_public_sources +
|
libsysprof_public_sources +
|
||||||
libsysprof_private_sources +
|
libsysprof_private_sources +
|
||||||
libsysprof_enums,
|
libsysprof_enums,
|
||||||
|
libsysprof_resources,
|
||||||
|
|
||||||
include_directories: [include_directories('.'),
|
include_directories: [include_directories('.'),
|
||||||
libsysprof_capture_include_dirs],
|
libsysprof_capture_include_dirs],
|
||||||
|
|||||||
@ -21,114 +21,16 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "sysprof-callgraph-private.h"
|
#include "sysprof-callgraph-private.h"
|
||||||
|
#include "sysprof-categories-private.h"
|
||||||
#include "sysprof-symbol-private.h"
|
#include "sysprof-symbol-private.h"
|
||||||
|
|
||||||
enum {
|
static SysprofCategories *categories;
|
||||||
RULE_PREFIX = 1,
|
|
||||||
RULE_EXACT,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _Rule
|
|
||||||
{
|
|
||||||
guint8 kind : 2;
|
|
||||||
SysprofCallgraphCategory category;
|
|
||||||
const char *match;
|
|
||||||
} Rule;
|
|
||||||
|
|
||||||
typedef struct _RuleGroup
|
|
||||||
{
|
|
||||||
const char *nick;
|
|
||||||
const Rule *rules;
|
|
||||||
} RuleGroup;
|
|
||||||
|
|
||||||
static RuleGroup rule_groups[] = {
|
|
||||||
{ "EGL",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "egl" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "FontConfig",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "GLib",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_main_loop_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_main_context_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "g_wakeup_" },
|
|
||||||
{ RULE_EXACT, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP, "g_main_dispatch" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "GTK 4",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_css_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_widget_measure" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gdk_snapshot" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_snapshot" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_widget_reposition" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_WINDOWING|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_window_present" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_ACTIONS|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_action_muxer_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_A11Y|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_accessible_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_A11Y|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_at_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_builder_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_buildable_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_widget_root" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gdk_frame_clock_paint" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "_gdk_frame_clock_emit_layout" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "_gdk_frame_clock_emit_paint" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "_gdk_frame_clock_emit_after_paint" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_INPUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gdk_surface_handle_event" },
|
|
||||||
{ RULE_EXACT, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gdk_surface_paint_on_clock" },
|
|
||||||
{ RULE_EXACT, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gdk_widget_render" },
|
|
||||||
{ RULE_EXACT, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gdk_widget_real_snapshot" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_PAINT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gsk_gl_" },
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_INPUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "gtk_im_" },
|
|
||||||
{ RULE_EXACT, SYSPROF_CALLGRAPH_CATEGORY_INPUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "do_update_im_spot_location" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "libc",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_EXACT, SYSPROF_CALLGRAPH_CATEGORY_MAIN_LOOP|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "poll" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Pango",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_LAYOUT|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Wayland Client",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_WINDOWING|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "wl_" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "Wayland Server",
|
|
||||||
(const Rule[]) {
|
|
||||||
{ RULE_PREFIX, SYSPROF_CALLGRAPH_CATEGORY_WINDOWING|SYSPROF_CALLGRAPH_CATEGORY_INHERIT, "wl_" },
|
|
||||||
{ 0 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
SysprofCallgraphCategory
|
SysprofCallgraphCategory
|
||||||
_sysprof_callgraph_node_categorize (SysprofCallgraphNode *node)
|
_sysprof_callgraph_node_categorize (SysprofCallgraphNode *node)
|
||||||
{
|
{
|
||||||
SysprofSymbol *symbol;
|
SysprofSymbol *symbol;
|
||||||
|
SysprofCallgraphCategory category;
|
||||||
|
|
||||||
g_return_val_if_fail (node, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
g_return_val_if_fail (node, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
||||||
g_return_val_if_fail (node->summary, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
g_return_val_if_fail (node->summary, SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED);
|
||||||
@ -145,27 +47,13 @@ _sysprof_callgraph_node_categorize (SysprofCallgraphNode *node)
|
|||||||
symbol->binary_nick == NULL)
|
symbol->binary_nick == NULL)
|
||||||
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
||||||
|
|
||||||
for (guint i = 0; i < G_N_ELEMENTS (rule_groups); i++)
|
if G_UNLIKELY (categories == NULL)
|
||||||
{
|
categories = sysprof_categories_new ();
|
||||||
if (strcmp (rule_groups[i].nick, symbol->binary_nick) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (guint j = 0; rule_groups[i].rules[j].kind; j++)
|
category = sysprof_categories_lookup (categories, symbol->binary_nick, symbol->name);
|
||||||
{
|
|
||||||
if (rule_groups[i].rules[j].kind == RULE_PREFIX)
|
|
||||||
{
|
|
||||||
if (g_str_has_prefix (symbol->name, rule_groups[i].rules[j].match))
|
|
||||||
return rule_groups[i].rules[j].category;
|
|
||||||
}
|
|
||||||
else if (rule_groups[i].rules[j].kind == RULE_EXACT)
|
|
||||||
{
|
|
||||||
if (strcmp (symbol->name, rule_groups[i].rules[j].match) == 0)
|
|
||||||
return rule_groups[i].rules[j].category;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
if (category == 0)
|
||||||
}
|
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
||||||
|
|
||||||
return SYSPROF_CALLGRAPH_CATEGORY_UNCATEGORIZED;
|
return category;
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/libsysprof/sysprof-categories-private.h
Normal file
35
src/libsysprof/sysprof-categories-private.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* sysprof-categories-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-callgraph.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _SysprofCategories SysprofCategories;
|
||||||
|
|
||||||
|
SysprofCategories *sysprof_categories_new (void);
|
||||||
|
void sysprof_categories_free (SysprofCategories *categories);
|
||||||
|
SysprofCallgraphCategory sysprof_categories_lookup (SysprofCategories *categories,
|
||||||
|
const char *binary_nick,
|
||||||
|
const char *symbol);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
279
src/libsysprof/sysprof-categories.c
Normal file
279
src/libsysprof/sysprof-categories.c
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
/* sysprof-categories.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 "libsysprof-resources.h"
|
||||||
|
|
||||||
|
#include "sysprof-callgraph-private.h"
|
||||||
|
#include "sysprof-categories-private.h"
|
||||||
|
#include "sysprof-enums.h"
|
||||||
|
|
||||||
|
#include "line-reader-private.h"
|
||||||
|
|
||||||
|
struct _SysprofCategories
|
||||||
|
{
|
||||||
|
GHashTable *binary_nick_to_rules;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MATCH_EXACT,
|
||||||
|
MATCH_PREFIX,
|
||||||
|
MATCH_SUFFIX,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _Rule
|
||||||
|
{
|
||||||
|
guint8 kind : 2;
|
||||||
|
guint8 inherit : 1;
|
||||||
|
guint8 category : 5;
|
||||||
|
char *match;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
static SysprofCallgraphCategory
|
||||||
|
parse_category (const char *category)
|
||||||
|
{
|
||||||
|
static GEnumClass *enum_class;
|
||||||
|
const GEnumValue *value;
|
||||||
|
|
||||||
|
if (enum_class == NULL)
|
||||||
|
enum_class = g_type_class_ref (SYSPROF_TYPE_CALLGRAPH_CATEGORY);
|
||||||
|
|
||||||
|
if (!(value = g_enum_get_value_by_nick (enum_class, category)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return value->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_rule (gpointer element)
|
||||||
|
{
|
||||||
|
Rule *rule = element;
|
||||||
|
|
||||||
|
g_clear_pointer (&rule->match, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sysprof_categories_add_rule (SysprofCategories *categories,
|
||||||
|
const char *binary_nick,
|
||||||
|
const char *match,
|
||||||
|
SysprofCallgraphCategory category,
|
||||||
|
gboolean inherit)
|
||||||
|
{
|
||||||
|
Rule rule;
|
||||||
|
GArray *ar;
|
||||||
|
|
||||||
|
g_assert (categories != NULL);
|
||||||
|
g_assert (binary_nick != NULL);
|
||||||
|
g_assert (match != NULL);
|
||||||
|
|
||||||
|
if (match[0] == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if G_UNLIKELY (!(ar = g_hash_table_lookup (categories->binary_nick_to_rules, binary_nick)))
|
||||||
|
{
|
||||||
|
ar = g_array_new (FALSE, FALSE, sizeof (Rule));
|
||||||
|
g_array_set_clear_func (ar, clear_rule);
|
||||||
|
g_hash_table_insert (categories->binary_nick_to_rules,
|
||||||
|
g_strdup (binary_nick),
|
||||||
|
ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match[0] == '*')
|
||||||
|
{
|
||||||
|
rule.kind = MATCH_SUFFIX;
|
||||||
|
rule.match = g_strdup (&match[1]);
|
||||||
|
rule.category = category;
|
||||||
|
rule.inherit = inherit;
|
||||||
|
|
||||||
|
g_array_append_val (ar, rule);
|
||||||
|
}
|
||||||
|
else if (match[strlen(match)-1] == '*')
|
||||||
|
{
|
||||||
|
rule.kind = MATCH_PREFIX;
|
||||||
|
rule.match = g_strndup (match, strlen (match)-1);
|
||||||
|
rule.category = category;
|
||||||
|
rule.inherit = inherit;
|
||||||
|
|
||||||
|
g_array_append_val (ar, rule);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rule.kind = MATCH_EXACT;
|
||||||
|
rule.match = g_strdup (match);
|
||||||
|
rule.category = category;
|
||||||
|
rule.inherit = inherit;
|
||||||
|
|
||||||
|
g_array_append_val (ar, rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysprofCategories *
|
||||||
|
sysprof_categories_new (void)
|
||||||
|
{
|
||||||
|
SysprofCategories *categories;
|
||||||
|
g_autoptr(GBytes) bytes = NULL;
|
||||||
|
g_autofree char *binary_nick = NULL;
|
||||||
|
const char *str;
|
||||||
|
const char *lineptr;
|
||||||
|
gsize line_len;
|
||||||
|
gsize len;
|
||||||
|
guint lineno = 0;
|
||||||
|
LineReader reader;
|
||||||
|
|
||||||
|
g_resources_register (libsysprof_get_resource ());
|
||||||
|
|
||||||
|
if (!(bytes = g_resources_lookup_data ("/org/gnome/libsysprof/categories.txt", 0, NULL)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(str = (const char *)g_bytes_get_data (bytes, &len)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
line_reader_init (&reader, (char *)str, len);
|
||||||
|
|
||||||
|
categories = g_new0 (SysprofCategories, 1);
|
||||||
|
categories->binary_nick_to_rules = g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
(GDestroyNotify)g_array_unref);
|
||||||
|
|
||||||
|
while ((lineptr = line_reader_next (&reader, &line_len)))
|
||||||
|
{
|
||||||
|
g_autofree char *line = g_strndup (lineptr, line_len);
|
||||||
|
SysprofCallgraphCategory category_value;
|
||||||
|
g_auto(GStrv) parts = NULL;
|
||||||
|
const char *match = NULL;
|
||||||
|
const char *category = NULL;
|
||||||
|
const char *inherit = NULL;
|
||||||
|
|
||||||
|
lineno++;
|
||||||
|
g_strstrip (line);
|
||||||
|
|
||||||
|
if (line[0] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Group lines look like "binary nick:\n" */
|
||||||
|
if (g_str_has_suffix (line, ":"))
|
||||||
|
{
|
||||||
|
line[line_len-1] = 0;
|
||||||
|
g_set_str (&binary_nick, g_strstrip (line));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = g_strsplit (line, " ", 0);
|
||||||
|
|
||||||
|
for (guint i = 0; parts[i]; i++)
|
||||||
|
{
|
||||||
|
g_strstrip (parts[i]);
|
||||||
|
|
||||||
|
if (parts[i][0] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (match == NULL)
|
||||||
|
{
|
||||||
|
match = parts[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category == NULL)
|
||||||
|
{
|
||||||
|
category = parts[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inherit == NULL)
|
||||||
|
{
|
||||||
|
inherit = parts[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match == NULL || category == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("categories.txt: line: %d: Incomplete rule", lineno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inherit && !g_str_equal (inherit, "inherit"))
|
||||||
|
{
|
||||||
|
g_warning ("categories.txt line %d: malformated inherit", lineno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(category_value = parse_category (category)))
|
||||||
|
{
|
||||||
|
g_warning ("categories.txt line %d: malformated category", lineno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sysprof_categories_add_rule (categories, binary_nick, match, category_value, !!inherit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sysprof_categories_free (SysprofCategories *categories)
|
||||||
|
{
|
||||||
|
if (categories != NULL)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&categories->binary_nick_to_rules, g_hash_table_unref);
|
||||||
|
g_free (categories);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysprofCallgraphCategory
|
||||||
|
sysprof_categories_lookup (SysprofCategories *categories,
|
||||||
|
const char *binary_nick,
|
||||||
|
const char *symbol)
|
||||||
|
{
|
||||||
|
GArray *rules;
|
||||||
|
|
||||||
|
if (binary_nick == NULL || symbol == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(rules = g_hash_table_lookup (categories->binary_nick_to_rules, binary_nick)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (guint i = 0; i < rules->len; i++)
|
||||||
|
{
|
||||||
|
const Rule *rule = &g_array_index (rules, Rule, i);
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
if (rule->kind == MATCH_EXACT)
|
||||||
|
ret = strcmp (rule->match, symbol) == 0;
|
||||||
|
else if (rule->kind == MATCH_PREFIX)
|
||||||
|
ret = g_str_has_prefix (symbol, rule->match);
|
||||||
|
else if (rule->kind == MATCH_SUFFIX)
|
||||||
|
ret = g_str_has_suffix (symbol, rule->match);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (rule->inherit)
|
||||||
|
return rule->category | SYSPROF_CALLGRAPH_CATEGORY_INHERIT;
|
||||||
|
|
||||||
|
return rule->category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user