|
From: Nicholas N. <nj...@ca...> - 2004-01-21 12:44:39
Attachments:
order
|
[apologies if you receive this twice; if so, please ignore the first version as it had mistakes] On Sat, 10 Jan 2004, Jeremy Fitzhardinge wrote: > So, I think the init ordering should be: > > 1. stage1 > 1. pad the client address space > 2. do_exec stage2 > 2. stage2:main() > 1. (do something to cope with .init sections of any > libraries we're using) > 2. initialize Segment list to reflect all current mappings > (VG_(init_memory) > 3. init Valgrind heap, make mmap() call VG_(mmap), deal > with brk/sbrk. > 4. init early error reporting (ie default output sink) > 5. set up any other padding > 6. collate arguments from all the possible sources, > generating a unified vg_argv[] array > 3. stage2:VG_(main)() > 1. parse vg_argv > 2. print errors/usage/early failures > 3. dlopen() the tool > 4. init everything else (may need to be after > do_exec(client) if it depends on the shape/placement of > the client address space) > 5. remove all padding/clear all mappings out of client > address space > 6. do_exec client/set up client stack > 7. start VCPU > > As you say, the break between main() and VG_(main) is pretty arbitrary. > Perhaps we should just drop stage2.c, move everything into vg_main.c, > rename VG_(main)() to main(), get rid of KickStartParams (another > historical name). I have a patch that does this -- removes stage2.c, moving it into vg_main.c. This allowed me to remove quite a lot of cruft, because the two were pretty closely intertwined. It also includes my .valgrindrc stuff, and a fix for bug 71126, as previously mentioned. It's at www.cl.cam.ac.uk/~njn25/startup-merge.patch (too big to mail). There are a couple of shortcomings still: no support for quoting in the .valgrindrc files, which Tom wants, and tool-specific CLOs can't have colons in them, which Josef wants. It seems to work ok. I tried my best to just refactor things, and not change any actual behaviour. I've attached a file that lists all the tasks now done in main(), and their dependencies. It doesn't look very much like your list above, Jeremy; mostly I kept the existing order of things. Valgrind has certainly become a tricky sucker to start up. I think these dependencies should eventually go into comments in main(); there are already some dependencies listed for the code that was VG_(main)(), and they're very useful. There is certainly potential for the order of startup events to change, and for neatening up, and fixing the mentioned shortcomings. However, if nobody objects, I'd like to put this patch in sooner rather than later since any intermediate commits could cause some pretty heinous clashes. N |
|
From: Jeremy F. <je...@go...> - 2004-01-21 21:17:54
|
On Wed, 2004-01-21 at 04:44, Nicholas Nethercote wrote: > I've attached a file that lists all the tasks now done in main(), > and their dependencies. It doesn't look very much like your list above, > Jeremy; mostly I kept the existing order of things. Valgrind has > certainly become a tricky sucker to start up. Yep. I wrote my list off the top of my head, so I'm not surprised it doesn't match something which actually works. > I think these dependencies > should eventually go into comments in main(); there are already some > dependencies listed for the code that was VG_(main)(), and they're very > useful. Agreed. > There is certainly potential for the order of startup events to change, > and for neatening up, and fixing the mentioned shortcomings. However, if > nobody objects, I'd like to put this patch in sooner rather than later > since any intermediate commits could cause some pretty heinous clashes. OK. It will clash a bit with the archdep patch, but I think sooner rather than later. > Loading everything (was stage2.c:main()): > > 1. Check launched by stage 1, with scan_auxv() [must be first] > 2. Begin working out address space layout [must be second] > 3. pad from client_base..valgrind_base [must be third] > 4. get vg_argv + cl_argv, from command-line or _VALGRIND_CLO [after ?] > 5. augment vg_argv from VALGRIND_OPTS and .valgrindrc [after 4] I think _VALGRIND_CLO should exclusively take precedence over all other sources of command-line options (so if it is present, then 5 is skipped). That's because it is constructed out of vg_argv, which in turn is constructed out of all the sources when V first starts. > 6. pre-process cmd-line, to find --tool and --exec [after 5] > 7. find client, check exists [after 6] ((move to before 14/15?)) May as well fail out early? > 8. set VG_(libdir) from VALGRINDLIB [after ??] ((move to after 3?)) Earlier is better. > 9. load/map in tool [after 6] > 10. get toolinfo (esp ratio) [after 9] > 11. check interface version matches [after 10] > 11b. Set heapblock-redzone size of V's allocator [after 10] > 12. finalise address space layout (shadow area, client area) [after 10] > 13. make redzone inaccessible [after 12] > 14. make client hole [after 12] > 15. load (do_exec) client [after 14] > 16. mmap shadow memory [after 12] > 17. unpad shadow_end..0xffffffff [after 12] This should probably be shadow_end..valgrind_mmap_end; this will leave the padding covering Valgrind's heap/stack, which will prevent unwanted mappings from ending up there. This could be problematic (since the stack won't be able to grow while the padding is there), so maybe the answer is to make sure the Segment list has already blocked out Valgrind's bss/heap/stack area for mapping, and just use VG_(mmap) for address space allocation - see below at init_memory). > 18. fix_environment [after 9; others?] > 19. setup client stack [after 18] > > Valgrind + tool initialisation (was vg_main.c:VG_(main)()): > > 20. do m_state_static, inc FPU state [after 19; where is have_ssestate setup? > looks like it's always True...] m_state_static is a holdover from the old code, and isn't really necessary anymore. It's just used to bootstrap the initial thread state, but we could do it more directly. The FPU state is pretty bogus - it just needs to be a not-completely-borked state. > 21. do atfork(NULL, NULL, newpid) > 22. work out file descriptor limits, reserve some fds [after ??] > 23. read proc/self/maps into buffer [after ??] > 24. call SK_(pre_clo_init) [after ??] > 25. tool_init_dlsym to setup tool functions [after 24] > 26. process command line opts [after 25] > 27. delay to hook GDB [after ??] Needs to be after 26. > 28. SK_(post_clo_init) [after 26] > 29. setup baseBlock [after 28] > 30. init_preopened_fds [after 26] > 31. scheduler_init [after ??] It needs the initial thread state (ie, eip and esp), but that's about it. > 32. proxy_init > 33. sigstartup_action [after 31] I seem to remember the relationships between 32 and 33 are pretty subtle. > 34. init internal profiling [after ??] > 35. start RDTSC calibration [after ??] > 36. init_memory [after 23? (so we can parse proc/self/maps); complex, because > it does several things] Maybe it should be split up. The most important thing it does is initialize the Segment list. This point represents the boundary between "mmap must be used, VG_(mmap) must not be used" and "VG_(mmap) must be used, mmap must not be used". Since this is a subtle distinction, and hard to police, I think it should happen as early as possible, and just make everyone use VG_(mmap). This is a bit tricky, since ume.c/do_exec uses mmap(), but maybe we can change it to use VG_(mmap), and give stage1 a stub definition of VG_(mmap). If it uses VG_(mmap), it may also be able to encode more information about the executable in the SF_* flags. > 37. load suppressions [after 25?] > 38. end RDTSC calibration [after 35] > 39. init TT/TC [after ??] > 40. setup code redirect table [after ??] > 41. install pointercheck, if necessary [after ??] 26. I think that's the only dependency. > 42. Run! > 43. finalisation... (errors, SK_(fini), counts, exit) J |
|
From: Jeremy F. <je...@go...> - 2004-01-21 21:27:33
|
On Wed, 2004-01-21 at 04:44, Nicholas Nethercote wrote: > I've attached a file that lists all the tasks now done in main(), > and their dependencies. It doesn't look very much like your list above, > Jeremy; mostly I kept the existing order of things. Valgrind has > certainly become a tricky sucker to start up. I think these dependencies > should eventually go into comments in main(); there are already some > dependencies listed for the code that was VG_(main)(), and they're very > useful. One other nice thing to do would be to drop all of stage2's use of malloc and fprintf(), and use the Valgrind equivalents (esp printf, since we want to report errors in a consistent way). Certainly mixing the use of VG_(arena_malloc)/malloc in vg_main just looks very strange. J |
|
From: Nicholas N. <nj...@ca...> - 2004-01-22 13:18:08
|
On Wed, 21 Jan 2004, Jeremy Fitzhardinge wrote: > One other nice thing to do would be to drop all of stage2's use of > malloc and fprintf(), and use the Valgrind equivalents (esp printf, > since we want to report errors in a consistent way). Certainly mixing > the use of VG_(arena_malloc)/malloc in vg_main just looks very strange. Avoiding malloc() is tricky. We can't use VG_(malloc)() (or VG_(arena_malloc)()) until the tool is loaded, and the redzone size is set. But quite a lot of things have to happen before then (eg. selecting the tool with --tool, loading the tool, etc.) fprintf() can probably be avoided more. N |
|
From: Nicholas N. <nj...@ca...> - 2004-01-22 22:15:24
|
On Wed, 21 Jan 2004, Jeremy Fitzhardinge wrote: > m_state_static is a holdover from the old code, and isn't really > necessary anymore. It's just used to bootstrap the initial thread > state, but we could do it more directly. I can see how to constant-propagate things so it's not needed, but that raises an interesting question -- it seems most of the registers in baseBlock never get properly initialised as such. It seems %esp and %eip and the fp-state are initialised, but the rest of them are never set in m_state_static before it gets copied into the baseBlock; thus, they get set to zero (because m_state_static is a static struct and thus zeroed initially). I'm guessing that careful m_state_static setup was necessary pre-FV, when Valgrind got control some time after the program had started. But now it gets control before any meaningful values are put in the GP regs (except %esp), so their contents can be junk? N |
|
From: Jeremy F. <je...@go...> - 2004-01-22 22:53:10
|
On Thu, 2004-01-22 at 14:15, Nicholas Nethercote wrote: > I can see how to constant-propagate things so it's not needed, but that > raises an interesting question -- it seems most of the registers in > baseBlock never get properly initialised as such. It seems %esp and %eip > and the fp-state are initialised, but the rest of them are never set in > m_state_static before it gets copied into the baseBlock; thus, they get > set to zero (because m_state_static is a static struct and thus zeroed > initially). > > I'm guessing that careful m_state_static setup was necessary pre-FV, when > Valgrind got control some time after the program had started. But now it > gets control before any meaningful values are put in the GP regs (except > %esp), so their contents can be junk? More or less. I think the ABI says all the GP int registers are meaningless except for edx, which Linux doesn't use and so zeros. Obviously we need to set all the segment regs up into sane states, but since we don't really use segments implicitly (we only pay attention to explicit segment overrides, which are typically fs and gs), it doesn't really matter. FP/MMX/SSE state also doesn't matter much, but we need to load it up with something saneish. J |
|
From: Nicholas N. <nj...@ca...> - 2004-01-22 23:36:37
|
On Thu, 22 Jan 2004, Nicholas Nethercote wrote: > fprintf() can probably be avoided more. Another question: is assert() necessary in vg_main.c? I tried inserting a vg_assert() right at the start of main(), it seemed to work fine. N |
|
From: Jeremy F. <je...@go...> - 2004-01-22 23:53:49
|
On Thu, 2004-01-22 at 15:36, Nicholas Nethercote wrote: > On Thu, 22 Jan 2004, Nicholas Nethercote wrote: > > > fprintf() can probably be avoided more. > > Another question: is assert() necessary in vg_main.c? I tried inserting > a vg_assert() right at the start of main(), it seemed to work fine. Well, OK then. So long as everything as assert_fail (or whatever we call it) is happy that early. J |
|
From: Doug R. <df...@nl...> - 2004-01-23 09:16:11
|
On Thu, 2004-01-22 at 22:51, Jeremy Fitzhardinge wrote: > On Thu, 2004-01-22 at 14:15, Nicholas Nethercote wrote: > > I can see how to constant-propagate things so it's not needed, but that > > raises an interesting question -- it seems most of the registers in > > baseBlock never get properly initialised as such. It seems %esp and %eip > > and the fp-state are initialised, but the rest of them are never set in > > m_state_static before it gets copied into the baseBlock; thus, they get > > set to zero (because m_state_static is a static struct and thus zeroed > > initially). > > > > I'm guessing that careful m_state_static setup was necessary pre-FV, when > > Valgrind got control some time after the program had started. But now it > > gets control before any meaningful values are put in the GP regs (except > > %esp), so their contents can be junk? > > More or less. I think the ABI says all the GP int registers are > meaningless except for edx, which Linux doesn't use and so zeros. > Obviously we need to set all the segment regs up into sane states, but > since we don't really use segments implicitly (we only pay attention to > explicit segment overrides, which are typically fs and gs), it doesn't > really matter. > > FP/MMX/SSE state also doesn't matter much, but we need to load it up > with something saneish. Isn't m_state_static also used to re-start the application when switching back to the real cpu for --stop-after=NN? Right now this doesn't work for me because it tries to load a set of null segment registers. |
|
From: Nicholas N. <nj...@ca...> - 2004-01-23 10:41:55
|
On Fri, 23 Jan 2004, Doug Rabson wrote: > Isn't m_state_static also used to re-start the application when > switching back to the real cpu for --stop-after=NN? Yes. I can remove the use of m_state_static use at startup -- working directly with the baseBlock instead -- but not when stopping like this. In principle I could use the baseBlock directly, but the baseBlock's layout is more complicated than m_state_static's, which makes it much harder to copy the values into the registers in vg_startup.S. It's easier to copy from the baseBlock into m_state_static, and then into the registers. > Right now this doesn't work for me because it tries to load a set of > null segment registers. I think it might be broken in general? Not sure. N |
|
From: Nicholas N. <nj...@ca...> - 2004-01-23 13:02:28
|
On Wed, 21 Jan 2004, Jeremy Fitzhardinge wrote: > I think _VALGRIND_CLO should exclusively take precedence over all other > sources of command-line options (so if it is present, then 5 is > skipped). That's because it is constructed out of vg_argv, which in > turn is constructed out of all the sources when V first starts. Done. > > 8. set VG_(libdir) from VALGRINDLIB [after ??] ((move to after 3?)) > > Earlier is better. Done. > > 17. unpad shadow_end..0xffffffff [after 12] > > This should probably be shadow_end..valgrind_mmap_end; this will leave > the padding covering Valgrind's heap/stack, which will prevent unwanted > mappings from ending up there. This could be problematic (since the > stack won't be able to grow while the padding is there), so maybe the > answer is to make sure the Segment list has already blocked out > Valgrind's bss/heap/stack area for mapping, and just use VG_(mmap) for > address space allocation - see below at init_memory). I've left it unchanged for the moment. > m_state_static is a holdover from the old code, and isn't really > necessary anymore. It's just used to bootstrap the initial thread > state, but we could do it more directly. Partially removed; still needed for VG_(switch_to_real_cpu) as discussed elsewhere in this thread. > > 36. init_memory [after 23? (so we can parse proc/self/maps); complex, because > > it does several things] > > Maybe it should be split up. The most important thing it does is > initialize the Segment list. This point represents the boundary between > "mmap must be used, VG_(mmap) must not be used" and "VG_(mmap) must be > used, mmap must not be used". Since this is a subtle distinction, and > hard to police, I think it should happen as early as possible, and just > make everyone use VG_(mmap). > > This is a bit tricky, since ume.c/do_exec uses mmap(), but maybe we can > change it to use VG_(mmap), and give stage1 a stub definition of > VG_(mmap). If it uses VG_(mmap), it may also be able to encode more > information about the executable in the SF_* flags. I've inlined VG_(init_memory), but not moved the bits about, because I'm uncertain about the dependencies of all the mapping stuff. ---- I've updated the patch, it's at: www.cl.cam.ac.uk/~njn25/startup-merge.patch2 I've made quite a few more simplifications, and merged together various steps that were closely related; it's looking relatively clean, now. I would like someone else to confirm it works on their machine before I commit it. Jeremy, would you mind going through and looking at all the places I've marked with XXX? I had various question about things I didn't understand, and marked things that are broken, and where improvements could be made but I wasn't sure how best to do it. You could annotate my patch, or I could commit and then let you make more changes, whatever you prefer. N |
|
From: Tom H. <th...@cy...> - 2004-01-23 14:23:15
|
In message <Pin...@ye...>
Nicholas Nethercote <nj...@ca...> wrote:
> I've updated the patch, it's at:
>
> www.cl.cam.ac.uk/~njn25/startup-merge.patch2
>
> I've made quite a few more simplifications, and merged together various
> steps that were closely related; it's looking relatively clean, now. I
> would like someone else to confirm it works on their machine before I
> commit it.
It seems largely OK to me. The main problem is that it doesn't compile
due to the VGP_PUSHCC(VgpStartup) and VGP_POPCC(VgpStartup) calls in
vg_main.c as VgpStartup doesn't seem to exist. Once I commented those
out it built and ran.
The only other thing I noticed is that it is printing a message
whenever it sees a --tool:option=value type switch - did you mean
to leave that in or is it just some debugging?
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-23 14:29:34
|
On Fri, 23 Jan 2004, Tom Hughes wrote: > > I've made quite a few more simplifications, and merged together various > > steps that were closely related; it's looking relatively clean, now. I > > would like someone else to confirm it works on their machine before I > > commit it. > > It seems largely OK to me. The main problem is that it doesn't compile > due to the VGP_PUSHCC(VgpStartup) and VGP_POPCC(VgpStartup) calls in > vg_main.c as VgpStartup doesn't seem to exist. Once I commented those > out it built and ran. Whoops, must edit vg_skin.h.base, not vg_skin.h. > The only other thing I noticed is that it is printing a message > whenever it sees a --tool:option=value type switch - did you mean > to leave that in or is it just some debugging? Just debugging, will remove. I'll update the patch on my website. Thanks. N |
|
From: Jeremy F. <je...@go...> - 2004-01-23 17:03:03
|
On Fri, 2004-01-23 at 01:15, Doug Rabson wrote: > Isn't m_state_static also used to re-start the application when > switching back to the real cpu for --stop-after=NN? Right now this > doesn't work for me because it tries to load a set of null segment > registers. Yes, but I think --stop-after=NN is terminally wounded. I don't think there's any way we can contrive to keep a working execution environment for the client without Valgrind these days, since even things like automatic stack growth are handled by V. J |
|
From: Nicholas N. <nj...@ca...> - 2004-01-23 17:20:34
|
On Fri, 23 Jan 2004, Jeremy Fitzhardinge wrote: > Yes, but I think --stop-after=NN is terminally wounded. I don't think > there's any way we can contrive to keep a working execution environment > for the client without Valgrind these days, since even things like > automatic stack growth are handled by V. Which is bad news for detecting bugs in the JIT-compiler; you can't do the binary search technique for finding erroneous BBs. (Well, you probably can if your error and the manifestation of it are close enough, but if it's a subtle error that doesn't manifest for a while, it won't work.) Any way we can achieve the same effect? N |
|
From: Jeremy F. <je...@go...> - 2004-01-23 18:07:16
|
On Fri, 2004-01-23 at 09:20, Nicholas Nethercote wrote: > Which is bad news for detecting bugs in the JIT-compiler; you can't do > the binary search technique for finding erroneous BBs. > > (Well, you probably can if your error and the manifestation of it are > close enough, but if it's a subtle error that doesn't manifest for a > while, it won't work.) > > Any way we can achieve the same effect? Well, it was always a fairly crippled mechanism, since it never worked with threaded programs, or if signals happened. I guess you could try to set up a limited environment which can coddle a bit more execution out of the client, but it might turn out to be a significant amount of work, which would be bad. And the more we do to improve Valgrind's virtualization, the less likely it is that we can maintain this easily. I agree with you about the debugging, but I don't really see how to achieve it. J |
|
From: Nicholas N. <nj...@ca...> - 2004-01-23 18:17:14
|
On Fri, 23 Jan 2004, Jeremy Fitzhardinge wrote: > I guess you could try to set up a limited environment which can coddle a > bit more execution out of the client, but it might turn out to be a > significant amount of work, which would be bad. And the more we do to > improve Valgrind's virtualization, the less likely it is that we can > maintain this easily. Would it be possible to do it another way -- keep Valgrind running, but pass through the original code untouched? You could still put it in the translation table/cache, etc. Or does the code get fiddled enough by V to make this difficult? |
|
From: Jeremy F. <je...@go...> - 2004-01-23 21:44:26
|
On Fri, 2004-01-23 at 10:17, Nicholas Nethercote wrote:
> Would it be possible to do it another way -- keep Valgrind running, but
> pass through the original code untouched? You could still put it in the
> translation table/cache, etc. Or does the code get fiddled enough by V to
> make this difficult?
Well, yes, that's what happens now, in a sense. --stop-after doesn't
make Valgrind evaporate, it just directly calls into the client code and
sets it going.
The trouble is that all the places in which V would normally interpose
itself will be unintercepted, so V can't do anything useful. This would
affect:
* stack growth - V normally catches SIGSEGV and grows the stack if
appropriate. We could leave a SIGSEGV handler in place to deal
with this, but if the client changes it, it loses
* signal syscalls - V normally does something special for all of
these, but they'll go straight to the kernel when running native
code
* threads - only the thread which happened to be running at
--stop-after will continue running; all the rest will be in
suspended animation
* client callbacks - anything the client was relying on client
callbacks for (most of libpthread, malloc, etc) will stop
working. Malloc is likely to be the most troublesome
So, if your client is single threaded, you aren't using a
malloc-intercepting tool, and the client doesn't want to grow its stack,
then it might be possible to keep running. With a fair amount of
engineering effort and complexity we can probably do better than this,
but it doesn't seem worth it.
J
|
|
From: Doug R. <df...@nl...> - 2004-01-23 18:29:24
|
On Fri, 2004-01-23 at 18:07, Jeremy Fitzhardinge wrote: > On Fri, 2004-01-23 at 09:20, Nicholas Nethercote wrote: > > Which is bad news for detecting bugs in the JIT-compiler; you can't do > > the binary search technique for finding erroneous BBs. > > > > (Well, you probably can if your error and the manifestation of it are > > close enough, but if it's a subtle error that doesn't manifest for a > > while, it won't work.) > > > > Any way we can achieve the same effect? > > Well, it was always a fairly crippled mechanism, since it never worked > with threaded programs, or if signals happened. > > I guess you could try to set up a limited environment which can coddle a > bit more execution out of the client, but it might turn out to be a > significant amount of work, which would be bad. And the more we do to > improve Valgrind's virtualization, the less likely it is that we can > maintain this easily. > > I agree with you about the debugging, but I don't really see how to > achieve it. Well if you are planning to drop this feature, it should tighten up the code generation for the low-overhead tools since you won't need the dec/test/branch at the beginning of each block, I guess. |
|
From: Nicholas N. <nj...@ca...> - 2004-01-23 18:39:09
|
On Fri, 23 Jan 2004, Doug Rabson wrote: > Well if you are planning to drop this feature, it should tighten up the > code generation for the low-overhead tools since you won't need the > dec/test/branch at the beginning of each block, I guess. Surely we could keep the feature, but only generate that testing code for each BB if somebody specifies --stop-after? Should be very easy to do. N |
|
From: Jeremy F. <je...@go...> - 2004-01-23 21:36:59
|
On Fri, 2004-01-23 at 10:28, Doug Rabson wrote: > Well if you are planning to drop this feature, it should tighten up the > code generation for the low-overhead tools since you won't need the > dec/test/branch at the beginning of each block, I guess. No, that code is there for thread context switching - the scheduler switches to a new thread after N basic blocks (50000, I think). It's use in --stop-after is secondary. J |
|
From: Doug R. <df...@nl...> - 2004-01-23 22:29:15
|
On Fri, 2004-01-23 at 21:34, Jeremy Fitzhardinge wrote: > On Fri, 2004-01-23 at 10:28, Doug Rabson wrote: > > Well if you are planning to drop this feature, it should tighten up the > > code generation for the low-overhead tools since you won't need the > > dec/test/branch at the beginning of each block, I guess. > > No, that code is there for thread context switching - the scheduler > switches to a new thread after N basic blocks (50000, I think). It's > use in --stop-after is secondary. I hadn't thought of that. Oh well - it seemed like a good idea at the time :-) |
|
From: Julian S. <js...@ac...> - 2004-01-24 09:55:49
|
On Friday 23 January 2004 18:07, Jeremy Fitzhardinge wrote: > On Fri, 2004-01-23 at 09:20, Nicholas Nethercote wrote: > > Which is bad news for detecting bugs in the JIT-compiler; you can't do > > the binary search technique for finding erroneous BBs. > > > > (Well, you probably can if your error and the manifestation of it are > > close enough, but if it's a subtle error that doesn't manifest for a > > while, it won't work.) > > > > Any way we can achieve the same effect? > > Well, it was always a fairly crippled mechanism, since it never worked > with threaded programs, or if signals happened. I think we should remove support for --stop-after. It's a shame, but I can't see how it can work any more. Even before FV etc, having to reduce reducing bug cases to non-threaded, non-signal handling versions was a serious limitation. If/when vcpu gets redesigned, we'll have to figure out some other way to track down bugs in it. > I guess you could try to set up a limited environment which can coddle a > bit more execution out of the client, but it might turn out to be a > significant amount of work, which would be bad. No ... that stuff is complex enough as it is, and complicating it just to support a not-very-usable debugging mode isn't a good idea. > I agree with you about the debugging, but I don't really see how to > achieve it. I think we're all in agreement. J |
|
From: Nicholas N. <nj...@ca...> - 2004-01-25 19:07:10
Attachments:
diff
|
On Sat, 24 Jan 2004, Julian Seward wrote: > I think we should remove support for --stop-after. Attached patch does so. N |