mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 08:00:53 +00:00
capture: fix sysprof_capture_reader_list_files()
This needs to stash the string pointers internally so that we can maintain ABI and still fix the issue at hand. Fixes #50
This commit is contained in:
@ -88,6 +88,8 @@ struct _SysprofCaptureReader
|
|||||||
int64_t end_time;
|
int64_t end_time;
|
||||||
SysprofCaptureStat st_buf;
|
SysprofCaptureStat st_buf;
|
||||||
unsigned int st_buf_set : 1;
|
unsigned int st_buf_set : 1;
|
||||||
|
char **list_files;
|
||||||
|
size_t n_list_files;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sets @errno on failure. Sets @errno to EBADMSG if the file magic doesn’t
|
/* Sets @errno on failure. Sets @errno to EBADMSG if the file magic doesn’t
|
||||||
@ -1276,7 +1278,7 @@ array_append (const char ***files,
|
|||||||
*files = new_files;
|
*files = new_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*files)[*n_files] = new_element;
|
(*files)[*n_files] = new_element ? strdup (new_element) : NULL;
|
||||||
*n_files = *n_files + 1;
|
*n_files = *n_files + 1;
|
||||||
assert (*n_files <= *n_files_allocated);
|
assert (*n_files <= *n_files_allocated);
|
||||||
|
|
||||||
@ -1304,6 +1306,16 @@ array_deduplicate (const char **files,
|
|||||||
*n_files = last_written + 1;
|
*n_files = last_written + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_strings (const void *a,
|
||||||
|
const void *b)
|
||||||
|
{
|
||||||
|
const char * const *astr = a;
|
||||||
|
const char * const *bstr = b;
|
||||||
|
|
||||||
|
return strcmp (*astr, *bstr);
|
||||||
|
}
|
||||||
|
|
||||||
const char **
|
const char **
|
||||||
sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
||||||
{
|
{
|
||||||
@ -1313,38 +1325,49 @@ sysprof_capture_reader_list_files (SysprofCaptureReader *self)
|
|||||||
|
|
||||||
assert (self != NULL);
|
assert (self != NULL);
|
||||||
|
|
||||||
while (sysprof_capture_reader_peek_type (self, &type))
|
/* Only generate the list of files once */
|
||||||
|
if (self->list_files == NULL)
|
||||||
{
|
{
|
||||||
const SysprofCaptureFileChunk *file;
|
while (sysprof_capture_reader_peek_type (self, &type))
|
||||||
|
|
||||||
if (type != SYSPROF_CAPTURE_FRAME_FILE_CHUNK)
|
|
||||||
{
|
{
|
||||||
sysprof_capture_reader_skip (self);
|
const SysprofCaptureFileChunk *file;
|
||||||
continue;
|
|
||||||
|
if (type != SYSPROF_CAPTURE_FRAME_FILE_CHUNK)
|
||||||
|
{
|
||||||
|
sysprof_capture_reader_skip (self);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(file = sysprof_capture_reader_read_file (self)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!array_append (&files, &n_files, &n_files_allocated, file->path))
|
||||||
|
{
|
||||||
|
free (files);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(file = sysprof_capture_reader_read_file (self)))
|
/* Sort and deduplicate the files array. */
|
||||||
break;
|
qsort (files, n_files, sizeof (*files), compare_strings);
|
||||||
|
array_deduplicate (files, &n_files);
|
||||||
|
|
||||||
if (!array_append (&files, &n_files, &n_files_allocated, file->path))
|
/* Add a null terminator */
|
||||||
|
if (!array_append (&files, &n_files, &n_files_allocated, NULL))
|
||||||
{
|
{
|
||||||
free (files);
|
free (files);
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->list_files = (char **)sysprof_steal_pointer (&files);
|
||||||
|
self->n_list_files = n_files; /* including NULL */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort and deduplicate the files array. */
|
/* Now copy the list but not the strings */
|
||||||
qsort (files, n_files, sizeof (*files), (int (*)(const void *, const void *)) strcmp);
|
files = malloc (sizeof (char *) * self->n_list_files);
|
||||||
array_deduplicate (files, &n_files);
|
memcpy (files, self->list_files, sizeof (char *) * self->n_list_files);
|
||||||
|
|
||||||
/* Add a null terminator */
|
|
||||||
if (!array_append (&files, &n_files, &n_files_allocated, NULL))
|
|
||||||
{
|
|
||||||
free (files);
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sysprof_steal_pointer (&files);
|
return sysprof_steal_pointer (&files);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user