gdb has N-squared behavior on getting registers when nptl threads on Linux are in use. gdb thrashes the register-cache. This is noticeably slow when the register count is large (over 300), such as Itanium: doing an interactive function call can take several seconds. Performance can be improved with more uses of CANNOT_FETCH_REGISTER and CANNOT_STORE_REGISTER because of the existence of large numbers of raw-register numbers that are not treated as raw. Changing regcache.c: if (CANNOT_STORE_REGISTER (regnum)) to regcache.c: if (!regcache->readonly_p && !CANNOT_FETCH_REGISTER(regnum)) regcache.c: if (CANNOT_STORE_REGISTER (regnum)) { thread-db.c: if(regno != -1 && CANNOT_FETCH_REGISTER(regno)) { thread-db.c: if(regno != -1 && CANNOT_STORE_REGISTER(regno)) { But that's a minor improvement as the time-delay is still noticeable. Here is a stack trace with a tiny bit of commentary (involving an interactive-function-call). The following shows gdb thrashing it's register cache. #0 registers_changed () at ../../src/gdb/regcache.c:530 #1 0x40000000001df9e0 in regcache_raw_supply (regcache=0x600000000012cea0, regnum=0, buf=0x0) at ../../src/gdb/regcache.c:1113 #2 0x40000000000cac50 in fetch_register (regnum=0) at ../../src/gdb/infptrace.c:289 #3 0x40000000000cb1d0 in fetch_inferior_registers (regnum=0) at ../../src/gdb/infptrace.c:327 #4 0x40000000000e5d20 in thread_db_fetch_registers (regno=-1) at ../../src/gdb/thread-db.c:1059 #5 0x40000000000dfaa0 in ps_lgetregs (ph=0x6000000000044a44, lwpid=31919, ps_lgetregs changes the value of inferior_ptid on entry {to perhaps 1277,1277,0} using the BUILD_LWP macro and requests all registers from the inferior. On return inferior_ptid of {1277,0, 25643240009} is restored. Which means that the register-cache gets thrashed. gregset=0x60000fffffff64a0) at ../../src/gdb/proc-service.c:235 #6 0x20000000025a4140 in td_thr_getgregs (th=0x60000000003f11a8, regset=0x60000fffffff64a0) at td_thr_getgregs.c:26 #7 0x40000000000e5e10 in thread_db_fetch_registers (regno=-1) at ../../src/gdb/thread-db.c:1066 #8 0x40000000000e65d0 in thread_db_store_registers (regno=351) Requests all registers. inferior ptid might be {1277,0, 25643240009} at ../../src/gdb/thread-db.c:1116 #9 0x40000000001dd590 in regcache_raw_write (regcache=0x600000000012cea0, regnum=351, buf=0x60000fffffff7d40) at ../../src/gdb/regcache.c:855 #10 0x40000000001dda60 in regcache_cooked_write (regcache=0x600000000012cea0, regnum=351, buf=0x60000fffffff7d40) at ../../src/gdb/regcache.c:874 #11 0x40000000001dd880 in deprecated_write_register_gen (regnum=351, buf=0x60000fffffff7d40 "\bÃÿ\177ÿ\017") at ../../src/gdb/regcache.c:865 #12 0x40000000001df4c0 in write_register (regnum=351, val=6917546617679627016) at ../../src/gdb/regcache.c:1073 #13 0x40000000000b51b0 in ia64_push_dummy_call (gdbarch=0x600000000012be10, function=0x6000000000467490, regcache=0x600000000012cea0, bp_addr=4611686018427389088, nargs=2, args=0x60000fffffff8048, sp=6917546619827102608, struct_return=0, struct_addr=0) at ../../src/gdb/ia64-tdep.c:3094 #14 0x40000000002d9150 in gdbarch_push_dummy_call ( One way to avoid thrashing the cache is to creat multiple register caches. Has this multiple-register-cache idea been considered seriously before? Is there any proposed outline-of-change? One alternative: registers_changed(), if altered to mean 'get rid of all existing caches' would then be safe and existing callers would be safe. ps_lgetregs (proc-service.c) could be changed to request a cache-switch (actually twice) so no more trashing. Minimally invasive and precise. Does this seem like a worthwhile change (abstractly I mean)? Are other designs better (such as...?)? Comments? Flames? David B. Anderson davea at sgi dot com http://reality.sgiweb.org/davea