[pacman-dev] memleak caused by "don't duplicate package in cache"
Xavier
shiningxc at gmail.com
Wed Feb 6 10:07:40 EST 2008
Previously, all installed packages were duplicated when added to the cache.
in libalpm/add.c :
801 >-if(_alpm_db_add_pkgincache(db, newpkg) == -1) {
And the _alpm_db_add_pkgincache function in cache.c duplicated the newpkg.
I wanted to avoid this duplication with the following commit :
http://projects.archlinux.org/git/?p=pacman.git;a=commit;h=8240da6cb3ff95ad480efe3e1876104024398fae
I simply removed the pkg_dup in that function. Since I removed a
pkg_dup, I had to remove the corresponding pkg_free call also.
Previously, the packages in the targets list were freed in the
_alpm_trans_free function. And the duplicated package in the cache were
freed in _alpm_db_free_pkgcache.
Since the cache is freed only when alpm is released, which happens at
the very end, I let the free there. So I removed it from
_alpm_trans_free, which is called when a transaction is released.
Now the ugly part begins. The targets are only added to the cache when
they are installed, not when they are removed (obviously). That explains
the condition I added in trans_free :
+ } else if (trans->type == PM_TRANS_TYPE_REMOVE ||
+ trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) {
alpm_list_free_inner(trans->packages,
(alpm_list_fn_free)_alpm_pkg_free);
So, when a whole install transaction goes fine, without errors,
everything works well. All targets are added to the cache, and are then
all freed correctly by the _alpm_db_free_pkgcache function.
However, when the transaction doesn't go correctly, the targets are
loaded in memory, but they are not installed, and so not freed! All
targets stay in memory, and cause a big memleak.
For example, a conflict could be detected, and the transaction is
aborted (as in sync400).
But it might even be possible that a transaction gets aborted in the
middle. Maybe because it ran out of memory, or because the user
interrupted it, or whatever.
So, for solving this issue, maybe we would need a way to track down
which packages were loaded in the cache. That should allow us to free
everything correctly, which doesn't seem possible currently.
We could then free in the trans_free function all targets that are not
in the pkg cache. And the remaining targets that are in the pkg cache
will be freed when the cache is freed.
More information about the pacman-dev
mailing list