You are not logged in.
Without alpm_list_msort():
Locally installed packages are printed from A-Z.
valgrind a.out
and
gcc -lalpm -g -fsanitize=leak,address,undefined ./listpkgs.c; ./a.out
show that no there are no leaks.
With alpm_list_msort() (change SORT_PKG_LIST macro constant from 0 to 1):
Locally installed packages are printed based on their installation size (from smallest to biggest).
valgrind a.out
and
gcc -lalpm -g -fsanitize=leak,address,undefined ./listpkgs.c; ./a.out
show that there are some leaks.
/* Compile with "gcc -g -lalpm listpkgs.c" */
#include <alpm.h>
#include <assert.h>
#include <stdio.h>
#define SORT_PKG_LIST 0
static void
print_pkg(alpm_pkg_t *pkg)
{
printf("%s: %ld\n", alpm_pkg_get_name(pkg), alpm_pkg_get_isize(pkg));
}
static void
iterate_over_pkg_list(alpm_list_t *pkg_list)
{
while (pkg_list != NULL) {
print_pkg((alpm_pkg_t *)pkg_list->data);
pkg_list = alpm_list_next(pkg_list);
}
}
#if SORT_PKG_LIST
static int
isize_comp(const void *pkg1, const void *pkg2)
{
return alpm_pkg_get_isize((alpm_pkg_t *)pkg1) >
alpm_pkg_get_isize((alpm_pkg_t *)pkg2);
}
static alpm_list_t *
get_sorted_pkg_list(alpm_db_t *db)
{
alpm_list_t *unsorted_pkg_list;
alpm_list_t *sorted_pkg_list;
unsorted_pkg_list = alpm_db_get_pkgcache(db);
assert(unsorted_pkg_list != NULL);
sorted_pkg_list = alpm_list_msort(
unsorted_pkg_list, alpm_list_count(unsorted_pkg_list), isize_comp);
return sorted_pkg_list;
}
#endif
int
main()
{
int retval;
alpm_handle_t *handle;
alpm_db_t *db;
alpm_list_t *pkg_list;
handle = alpm_initialize("/", "/var/lib/pacman/", NULL);
assert(handle != NULL);
db = alpm_get_localdb(handle);
#if SORT_PKG_LIST
pkg_list = get_sorted_pkg_list(db);
#else
pkg_list = alpm_db_get_pkgcache(db);
assert(pkg_list != NULL);
#endif
iterate_over_pkg_list(pkg_list);
retval = alpm_release(handle);
assert(retval == 0);
}
I've taken a look at libalpm_list(3) and the man page does not mention anything about freeing memory after calling alpm_list_msort().
Any help please?
Last edited by Aptrug (2022-03-26 14:05:22)
Offline
It is late at night, so I have not looked too deeply, but I'm guessing that the pointer stored in db->pkgcache no longer points to the top of the list after the msort, so not all entries are freed in alpm_release(). Note the alpm_list_t essentially points at the first element - it is a very simple list... Though not documented, it seems the list should not be altered. Doing a copy and free fixes it
db = alpm_get_localdb(handle);
pkg_list = alpm_list_copy(alpm_db_get_pkgcache(db));
assert(pkg_list != NULL);
pkg_list = alpm_list_msort(
pkg_list, alpm_list_count(pkg_list), isize_comp);
iterate_over_pkg_list(pkg_list);
alpm_list_free(pkg_list);
Offline