I've instructed myself a bit on how to use gdb and went after the bug. Here's a stack trace of the bug in action:
(gdb) bt
#0 0x00007ffff31a9c53 in __select_nocancel ()
at ../sysdeps/unix/syscall-template.S:82
#1 0x00007ffff7b6cd69 in pkgAcquire::Run (this=0x7fffffffc830,
PulseIntervall=<value optimized out>) at acquire.cc:346
#2 0x00007ffff7b666c2 in ListUpdate (Stat=<value optimized out>, List=...,
PulseInterval=5000) at algorithms.cc:1367
#3 0x00000000004653a9 in RPackageLister::updateCache (
this=<value optimized out>, status=0xa80d00, error=...)
at rpackagelister.cc:1301
#4 0x0000000000440148 in RGMainWindow::cbUpdateClicked (
self=<value optimized out>, data=0x75ba70) at rgmainwindow.cc:2999
What's happening here is that synaptic is using the apt libraries to run a tight loop using select to update the progress bar status. In RPackageLister::updateCache, line 1301 is:
bool res = ListUpdate(*status, *_cache->list(), 5000);
That eventually gets used as tv.tv_usec in a select() call making this a select loop where each select only waits for 0.005 seconds. I tried bumping that value to 500000 (0.5 seconds) and it solves the CPU problem but because the code is single threaded it slows down the whole interface. A more involved patch is needed.
I've instructed myself a bit on how to use gdb and went after the bug. Here's a stack trace of the bug in action:
(gdb) bt unix/syscall- template. S:82 fc830, all=<value optimized out>) at acquire.cc:346 al=5000) at algorithms.cc:1367 :updateCache ( cc:1301 :cbUpdateClicke d ( cc:2999
#0 0x00007ffff31a9c53 in __select_nocancel ()
at ../sysdeps/
#1 0x00007ffff7b6cd69 in pkgAcquire::Run (this=0x7ffffff
PulseInterv
#2 0x00007ffff7b666c2 in ListUpdate (Stat=<value optimized out>, List=...,
PulseInterv
#3 0x00000000004653a9 in RPackageLister:
this=<value optimized out>, status=0xa80d00, error=...)
at rpackagelister.
#4 0x0000000000440148 in RGMainWindow:
self=<value optimized out>, data=0x75ba70) at rgmainwindow.
What's happening here is that synaptic is using the apt libraries to run a tight loop using select to update the progress bar status. In RPackageLister: :updateCache, line 1301 is:
bool res = ListUpdate(*status, *_cache->list(), 5000);
That eventually gets used as tv.tv_usec in a select() call making this a select loop where each select only waits for 0.005 seconds. I tried bumping that value to 500000 (0.5 seconds) and it solves the CPU problem but because the code is single threaded it slows down the whole interface. A more involved patch is needed.