diff --git a/src/libsysprof-profile/sysprof-linux-instrument.c b/src/libsysprof-profile/sysprof-linux-instrument.c index f43b56b7..4d715064 100644 --- a/src/libsysprof-profile/sysprof-linux-instrument.c +++ b/src/libsysprof-profile/sysprof-linux-instrument.c @@ -23,6 +23,7 @@ #include #include "sysprof-linux-instrument-private.h" +#include "sysprof-maps-parser-private.h" #include "sysprof-podman-private.h" #include "sysprof-recording-private.h" @@ -40,8 +41,6 @@ enum { G_DEFINE_FINAL_TYPE (SysprofLinuxInstrument, sysprof_linux_instrument, SYSPROF_TYPE_INSTRUMENT) -static GRegex *address_range_regex; - static char ** sysprof_linux_instrument_list_required_policy (SysprofInstrument *instrument) { @@ -57,9 +56,9 @@ add_mmaps (SysprofRecording *recording, gboolean ignore_inode) { SysprofCaptureWriter *writer; - LineReader reader; - const char *line; - gsize line_len; + SysprofMapsParser parser; + guint64 begin, end, offset, inode; + char *file; g_assert (SYSPROF_IS_RECORDING (recording)); g_assert (mapsstr != NULL); @@ -67,67 +66,22 @@ add_mmaps (SysprofRecording *recording, writer = _sysprof_recording_writer (recording); - line_reader_init (&reader, (char *)mapsstr, -1); - while ((line = line_reader_next (&reader, &line_len))) + sysprof_maps_parser_init (&parser, mapsstr, -1); + while (sysprof_maps_parser_next (&parser, &begin, &end, &offset, &inode, &file)) { - g_autoptr(GMatchInfo) match_info = NULL; + if (ignore_inode) + inode = 0; - if (g_regex_match_full (address_range_regex, line, line_len, 0, 0, &match_info, NULL)) - { - g_autofree char *file = NULL; - guint64 begin_addr; - guint64 end_addr; - guint64 inode; - guint64 offset; - gboolean is_vdso; - int begin_addr_begin; - int begin_addr_end; - int end_addr_begin; - int end_addr_end; - int offset_begin; - int offset_end; - int inode_begin; - int inode_end; - int path_begin; - int path_end; - - if (!g_match_info_fetch_pos (match_info, 1, &begin_addr_begin, &begin_addr_end) || - !g_match_info_fetch_pos (match_info, 2, &end_addr_begin, &end_addr_end) || - !g_match_info_fetch_pos (match_info, 3, &offset_begin, &offset_end) || - !g_match_info_fetch_pos (match_info, 4, &inode_begin, &inode_end) || - !g_match_info_fetch_pos (match_info, 5, &path_begin, &path_end)) - continue; - - begin_addr = g_ascii_strtoull (&line[begin_addr_begin], NULL, 16); - end_addr = g_ascii_strtoull (&line[end_addr_begin], NULL, 16); - offset = g_ascii_strtoull (&line[offset_begin], NULL, 16); - inode = g_ascii_strtoull (&line[inode_begin], NULL, 10); - - if (memcmp (" (deleted", - &line[path_end] - strlen (" (deleted"), - strlen (" (deleted")) == 0) - path_end -= strlen (" (deleted)"); - - file = g_strndup (&line[path_begin], path_end-path_begin); - - is_vdso = strcmp ("[vdso]", file) == 0; - - if (ignore_inode || is_vdso) - inode = 0; - - if (is_vdso) - offset = 0; - - sysprof_capture_writer_add_map (writer, - SYSPROF_CAPTURE_CURRENT_TIME, - -1, - pid, - begin_addr, - end_addr, - offset, - inode, - file); - } + sysprof_capture_writer_add_map (writer, + SYSPROF_CAPTURE_CURRENT_TIME, + -1, + pid, + begin, + end, + offset, + inode, + file); + g_free (file); } } @@ -402,7 +356,6 @@ sysprof_linux_instrument_class_init (SysprofLinuxInstrumentClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); SysprofInstrumentClass *instrument_class = SYSPROF_INSTRUMENT_CLASS (klass); - g_autoptr(GError) error = NULL; object_class->finalize = sysprof_linux_instrument_finalize; @@ -410,12 +363,6 @@ sysprof_linux_instrument_class_init (SysprofLinuxInstrumentClass *klass) instrument_class->prepare = sysprof_linux_instrument_prepare; instrument_class->record = sysprof_linux_instrument_record; instrument_class->process_started = sysprof_linux_instrument_process_started; - - address_range_regex = g_regex_new ("^([0-9a-f]+)-([0-9a-f]+) [r\\-][w\\-][x\\-][ps\\-] [0-9a-f]+ [0-9]{2}:[0-9]{2} ([0-9]+) +(.*)$", - G_REGEX_OPTIMIZE, - G_REGEX_MATCH_DEFAULT, - &error); - g_assert_no_error (error); } static void