On May 18, 2012, at 7:48 PM, Lawrence Crowl wrote:
> On 5/17/12, Mike Stump <[email protected]> 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?!
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.
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.
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.
> 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.