On 5/21/12, Mike Stump <mikest...@comcast.net> wrote: > On May 18, 2012, at 7:48 PM, Lawrence Crowl wrote: >> On 5/17/12, Mike Stump <mikest...@comcast.net> wrote: >>> On May 17, 2012, at 2:41 PM, Lawrence Crowl wrote: >>>>> Reusing the compiler for this seems like the only way to go. >>>>> But, we did look at using g++ to parse C++ expressions from gdb, >>>>> and it was too slow :-(. We're going to look again, at least to >>>>> generate some bug reports if we can. >>>> >>>> It's a tough problem, particularly as C/C++ and their compilers >>>> were not designed for a read-eval-print-loop environment. >>> >>> This of course is trivial to do, >> >> I do not think that word means what you think it means. :-) > > Excellent reference... Yeah, well, just a little more work to do: > > $ ./eval > extern "C" int printf(const char *...); int &k2 = *(int*)4294971592; > void eval() { printf("k is %d\n", k2); } > about to run > k is 42 > done running, took 32540 usecs > > Notice, this sucked a int k2 = 42; that was a variable inside > the context in which I wanted a k2. The nature of the variable > is irrelevant, could be a stack variable, could be a global, > a static top-level, all I need to know, is where it is (the > address) and the type and I generate a binding stub for it into > the context, and presto, complete access to most all variables. > This does make use of C++ to manage the variables in a slightly > nicer way. One either has to inject all variables and functions > into the context into which the program fragment is compiled, > or notice which variables and function are or might be used and > inject just those. > > I've seen ptype foo print the types of variables, so, it isn't > far off, and certainly gdb knows about the symbol table and can > figure out the addresses of those variables, right?!
For variables that are not optimized out of memory, I think this can work. But if you need to go for registers, or undo a variable elimination, the effort gets harder. > > Now, certainly one can find additional issues, and yes, there > is a bit of work to get 100% reliability that we'd like from > the scheme. For example, packed structures would need work, as > ptype isn't going to get that right from that start. I think the > functionality one would get would be good enough to start with, > and in time, better support for things ptype doesn't get right > would fix a certain class of problems. Agreed. > > So, what another 1000 lines to generate the context for the > fragment... I guess finding references could be annoying, and the > time required to generate and compile the entire context could > be annoying... > > Doing C++ would be harder, though, not quite for the reason > you gave. > >> I like the example, but it sidesteps the main problem, which is >> putting the expression in the context from which it was called. >> For instance if I stop in the middle of a function and type >> >> print foo->bar( a + b ) >> >> I need to find the find the variable names, lookup their types, > > ptype a does the lookup for a, and finds the type, so that isn't > hard, same with b and foo. Harder would be to synthesize the > context for the fragment to live in. To do this and work with > templates, you'd need the entire template bodies to be in the > debug information and to output them when generating the context > that might use them. Yes, you essentially need to come close to sending the compiler's symbol tables through the debug information. I don't know of any compiler/debugger pair that is close to that capability. That said, I don't know all such pairs either. > > class A { > foo() { } > } > > when stopped in foo, one needs to generate: > > class A { > foo(); > __eval() { fragment } > } > > and then call __eval(lookup("this"))... The compiler does > the overload resolution, the template instantiation and so on. > To ensure the compiler does name loookup right, one just needs > to generate the context for that fragment carefully. Agreed. >> do overload resolution, possibly do template instantiation, etc, >> all as if the compiler was in the scope defined for the line that >> the debugger is stopped at. That's the hard part. I'm not saying that the task is impossible, only that there is a lot of work to do before we get there. -- Lawrence Crowl