diff --git a/src/libsysprof-analyze/sysprof-document-file-private.h b/src/libsysprof-analyze/sysprof-document-file-private.h index c904124d..4f61b926 100644 --- a/src/libsysprof-analyze/sysprof-document-file-private.h +++ b/src/libsysprof-analyze/sysprof-document-file-private.h @@ -25,6 +25,7 @@ G_BEGIN_DECLS SysprofDocumentFile *_sysprof_document_file_new (const char *path, - GPtrArray *file_chunks); + GPtrArray *file_chunks, + gboolean compressed); G_END_DECLS diff --git a/src/libsysprof-analyze/sysprof-document-file.c b/src/libsysprof-analyze/sysprof-document-file.c index aa380b61..dd7526c8 100644 --- a/src/libsysprof-analyze/sysprof-document-file.c +++ b/src/libsysprof-analyze/sysprof-document-file.c @@ -26,9 +26,10 @@ struct _SysprofDocumentFile { - GObject parent_instance; - char *path; + GObject parent_instance; + char *path; GPtrArray *file_chunks; + guint compressed : 1; }; enum { @@ -104,7 +105,8 @@ sysprof_document_file_init (SysprofDocumentFile *self) SysprofDocumentFile * _sysprof_document_file_new (const char *path, - GPtrArray *file_chunks) + GPtrArray *file_chunks, + gboolean compressed) { SysprofDocumentFile *self; @@ -114,6 +116,7 @@ _sysprof_document_file_new (const char *path, self = g_object_new (SYSPROF_TYPE_DOCUMENT_FILE, NULL); self->path = g_strdup (path); self->file_chunks = file_chunks; + self->compressed = !!compressed; return self; } @@ -169,7 +172,7 @@ sysprof_document_file_dup_bytes (SysprofDocumentFile *self) GInputStream * sysprof_document_file_read (SysprofDocumentFile *self) { - GInputStream *input; + g_autoptr(GInputStream) input = NULL; g_return_val_if_fail (SYSPROF_IS_DOCUMENT_FILE (self), NULL); @@ -193,6 +196,13 @@ sysprof_document_file_read (SysprofDocumentFile *self) g_memory_input_stream_add_bytes (G_MEMORY_INPUT_STREAM (input), bytes); } + if (self->compressed) + { + g_autoptr(GZlibDecompressor) zlib = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); + + return g_converter_input_stream_new (input, G_CONVERTER (zlib)); + } + return g_steal_pointer (&input); } diff --git a/src/libsysprof-analyze/sysprof-document.c b/src/libsysprof-analyze/sysprof-document.c index 27f42a96..bdefa231 100644 --- a/src/libsysprof-analyze/sysprof-document.c +++ b/src/libsysprof-analyze/sysprof-document.c @@ -895,14 +895,19 @@ SysprofDocumentFile * sysprof_document_lookup_file (SysprofDocument *self, const char *path) { + g_autofree char *gz_path = NULL; gpointer key, value; g_return_val_if_fail (SYSPROF_IS_DOCUMENT (self), NULL); g_return_val_if_fail (path != NULL, NULL); - if (g_hash_table_lookup_extended (self->files_first_position, path, &key, &value)) + gz_path = g_strdup_printf ("%s.gz", path); + + if (g_hash_table_lookup_extended (self->files_first_position, path, &key, &value) || + g_hash_table_lookup_extended (self->files_first_position, gz_path, &key, &value)) { g_autoptr(GPtrArray) file_chunks = g_ptr_array_new_with_free_func (g_object_unref); + const char *real_path = key; EggBitsetIter iter; guint target = GPOINTER_TO_SIZE (value); guint i; @@ -913,7 +918,7 @@ sysprof_document_lookup_file (SysprofDocument *self, { g_autoptr(SysprofDocumentFileChunk) file_chunk = sysprof_document_get_item ((GListModel *)self, i); - if (g_strcmp0 (path, sysprof_document_file_chunk_get_path (file_chunk)) == 0) + if (g_strcmp0 (real_path, sysprof_document_file_chunk_get_path (file_chunk)) == 0) { gboolean is_last = sysprof_document_file_chunk_get_is_last (file_chunk); @@ -926,7 +931,9 @@ sysprof_document_lookup_file (SysprofDocument *self, while (egg_bitset_iter_next (&iter, &i)); } - return _sysprof_document_file_new (path, g_steal_pointer (&file_chunks)); + return _sysprof_document_file_new (path, + g_steal_pointer (&file_chunks), + g_strcmp0 (real_path, gz_path) == 0); } return NULL; @@ -957,6 +964,7 @@ sysprof_document_list_files (SysprofDocument *self) { g_autoptr(SysprofDocumentFile) file = NULL; g_autoptr(GPtrArray) file_chunks = g_ptr_array_new_with_free_func (g_object_unref); + g_autofree char *no_gz_path = NULL; const char *path = key; guint target = GPOINTER_TO_SIZE (value); guint i; @@ -980,7 +988,12 @@ sysprof_document_list_files (SysprofDocument *self) while (egg_bitset_iter_next (&iter, &i)); } - file = _sysprof_document_file_new (path, g_steal_pointer (&file_chunks)); + if (g_str_has_suffix (path, ".gz")) + path = no_gz_path = g_strndup (path, strlen (path) - 3); + + file = _sysprof_document_file_new (path, + g_steal_pointer (&file_chunks), + no_gz_path != NULL); g_list_store_append (model, file); } diff --git a/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c b/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c index 2ba237cc..b87c42aa 100644 --- a/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c +++ b/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c @@ -191,10 +191,9 @@ sysprof_kallsyms_symbolizer_prepare_async (SysprofSymbolizer *symbolizer, { SysprofKallsymsSymbolizer *self = (SysprofKallsymsSymbolizer *)symbolizer; g_autoptr(SysprofDocumentFile) file = NULL; - g_autoptr(GZlibDecompressor) decompressor = NULL; - g_autoptr(GInputStream) input_gz = NULL; g_autoptr(GInputStream) input = NULL; g_autoptr(GTask) task = NULL; + GInputStream *base_stream; g_assert (SYSPROF_IS_KALLSYMS_SYMBOLIZER (self)); g_assert (SYSPROF_IS_DOCUMENT (document)); @@ -203,9 +202,12 @@ sysprof_kallsyms_symbolizer_prepare_async (SysprofSymbolizer *symbolizer, task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, sysprof_kallsyms_symbolizer_prepare_async); - if (self->stream == NULL) + base_stream = self->stream; + + if (base_stream == NULL) { - if (!(file = sysprof_document_lookup_file (document, "/proc/kallsyms.gz"))) + + if (!(file = sysprof_document_lookup_file (document, "/proc/kallsyms"))) { g_task_return_new_error (task, G_IO_ERROR, @@ -214,20 +216,15 @@ sysprof_kallsyms_symbolizer_prepare_async (SysprofSymbolizer *symbolizer, return; } - decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); - input_gz = sysprof_document_file_read (file); - input = g_converter_input_stream_new (input_gz, G_CONVERTER (decompressor)); + base_stream = input = sysprof_document_file_read (file); + } - g_task_set_task_data (task, - g_data_input_stream_new (input), - g_object_unref); - } - else - { - g_task_set_task_data (task, - g_steal_pointer (&self->stream), - g_object_unref); - } + g_assert (base_stream != NULL); + g_assert (G_IS_INPUT_STREAM (base_stream)); + + g_task_set_task_data (task, + g_data_input_stream_new (base_stream), + g_object_unref); g_task_run_in_thread (task, sysprof_kallsyms_symbolizer_prepare_worker); } @@ -364,9 +361,7 @@ sysprof_kallsyms_symbolizer_new_for_symbols (GInputStream *symbols) g_return_val_if_fail (G_IS_INPUT_STREAM (symbols), NULL); self = g_object_new (SYSPROF_TYPE_KALLSYMS_SYMBOLIZER, NULL); - self->stream = G_INPUT_STREAM (g_data_input_stream_new (symbols)); - - g_object_unref (symbols); + self->stream = symbols; return SYSPROF_SYMBOLIZER (self); }