|
From: Adam G. <ar...@cy...> - 2003-04-28 11:41:01
Attachments:
vg.transtab.patch
|
Flushing the translation cache using the DISCARD_TRANSLATIONS user request doesn't always work - if the code has already been executed, basic blocks which chain to the one to be discarded are ignored. This means that modified code sometimes behaves as if it has not been modified! The attached patch makes VG_(invalidate_translations)() take a flag indicating whether basic blocks which chain to the discarded blocks should also be discarded. I did originally _always_ use this behaviour, but it is painfully slow when a shared object is unmapped. Seeya, Adam -- Real Programmers don't comment their code. If it was hard to write, it should be hard to read, and even harder to modify. These are all my own opinions. |
|
From: Julian S. <js...@ac...> - 2003-04-28 16:04:32
|
On Monday 28 April 2003 12:39 pm, Adam Gundy wrote: > Flushing the translation cache using the DISCARD_TRANSLATIONS user request > doesn't always work - if the code has already been executed, basic blocks > which chain to the one to be discarded are ignored. > > This means that modified code sometimes behaves as if it has not been > modified! > > The attached patch makes VG_(invalidate_translations)() take a flag > indicating whether basic blocks which chain to the discarded blocks should > also be discarded. > > I did originally _always_ use this behaviour, but it is painfully slow when > a shared object is unmapped. But the thing is, don't we _always_ have to unchain translations when discarding code, in order that this is ever safe? Hmm. Tell me if this logic is OK. If some tiny fragment of code is discarded, we have to unchain everything to make it safe; this is the safe but general case. If a complete .so's text section is munmapped, we can sort-of get away with just dumping the relevant translations. This is all highly dubious since it assumes that no translations of code in some other mapped text segment chain to those in the segment we're discarding. What guarantees that? I guess it must be the surrounding program logic, which knows not to call functions in .so's it has munmapped (dlclosed at a higher level). I am a bit confused here ... I must say I'm not happy about this level of fragileness and didn't realise V behaved this way by default. How horribly does unchaining trash your performance? I wonder if there is anything we can do to reduce the cost of it. J |
|
From: Adam G. <ar...@cy...> - 2003-04-28 16:30:17
|
At 17:04 28/04/03 +0100, Julian Seward wrote: >On Monday 28 April 2003 12:39 pm, Adam Gundy wrote: >> Flushing the translation cache using the DISCARD_TRANSLATIONS user request >> doesn't always work - if the code has already been executed, basic blocks >> which chain to the one to be discarded are ignored. >> >> This means that modified code sometimes behaves as if it has not been >> modified! >> >> The attached patch makes VG_(invalidate_translations)() take a flag >> indicating whether basic blocks which chain to the discarded blocks should >> also be discarded. >> >> I did originally _always_ use this behaviour, but it is painfully slow when >> a shared object is unmapped. > >But the thing is, don't we _always_ have to unchain translations when >discarding code, in order that this is ever safe? > >Hmm. Tell me if this logic is OK. > >If some tiny fragment of code is discarded, we have to unchain everything >to make it safe; this is the safe but general case. erk. no - we only have to unchain things that chain directly to that tiny fragment. The problem is the stale 'chain' jumps that are left lying around - when we unchain them, the jumps get set to VG_(patch_me)(), so that if the chain gets called, things get patched up. see VG_(unchain_jumpsite)(). >If a complete .so's text section is munmapped, we can sort-of get away with >just dumping the relevant translations. This is all highly dubious since >it assumes that no translations of code in some other mapped text segment >chain to those in the segment we're discarding. What guarantees that? >I guess it must be the surrounding program logic, which knows not to call >functions in .so's it has munmapped (dlclosed at a higher level). I am >a bit confused here ... the surrounding program logic. I hope. in practice anyone calling a function in a shared object which has been dlclosed() has already been rewarded with a SEGV - they don't need to be using valgrind for that... >I must say I'm not happy about this level of fragileness and didn't realise >V behaved this way by default. How horribly does unchaining trash your >performance? I wonder if there is anything we can do to reduce the cost >of it. unchaining shared objects affects performance _really_ badly. Try changing the False to True in VG_(remove_if_exe_segment)(). valgrind will take 10+ seconds on a fast machine every time a shared object is unloaded. this happens quite a lot on Linux (and even more under WINE)... I tried a few performance enhancements, like trying to batch up the 'unchain' scans, merging multiple basic block regions needing unchaining into single blocks etc. none of it helped very much. the big problem is that although the shared object is a contiguous chunk of memory, the translated basic blocks _aren't_; they're spread all over the translation cache :-( Seeya, Adam -- Real Programmers don't comment their code. If it was hard to write, it should be hard to read, and even harder to modify. These are all my own opinions. |