[lldb-dev] Evaluate expression for template class

Jim Ingham via lldb-dev lldb-dev at lists.llvm.org
Tue Jul 23 18:05:31 PDT 2019


Interesting...  What lldb & clang were you using?  With current TOT clang & lldb I see:

(lldb) run
Process 83732 launched: '/tmp/template2' (x86_64)
Process 83732 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000fad template2`main at template.cpp:12
   9   	
   10  	int main() {
   11  	  foo<void> test2;
-> 12  	  return 0;
    	  ^
   13  	}

(lldb) expr sizeof(test)
(unsigned long) $0 = 4
(lldb) expr sizeof(test2)
(unsigned long) $1 = 4

That's good, we do know about both of these, but:

(lldb) expr sizeof(foo<void>)
error: use of undeclared identifier 'foo'
error: expected '(' for function-style cast or type construction
error: expected expression
(lldb) expr sizeof(foo<int>)
error: use of undeclared identifier 'foo'
error: expected '(' for function-style cast or type construction
error: expected expression

Jim


> On Jul 23, 2019, at 5:49 PM, Scott Funkenhauser <sfunkenhauser at google.com> wrote:
> 
> I built with both clang and gcc, the behavior is the same (lldb fails to evaluate the expression, gdb succeeds).
> 
> Trying to evaluate a template type that hasn't been instantiated fails in both lldb and gdb.
> ie.
> (gdb) p sizeof(foo<double>)
> No symbol "foo<double>" in current context.
> (lldb) p sizeof(foo<double>)
> error: implicit instantiation of undefined template 'foo<double>'
> template is declared here
> 
> Looking at the debug info, both template instantiations are there, it seems like LLDB just isn't finding it (while GDB is).
> 
>  $readelf --debug-dump a.out | grep foo
>   0x00000000 666f6f00 5400696e 7400666f 6f3c696e foo.T.int.foo<in
>   0x00000080 00746573 74320066 6f6f3c76 6f69643e .test2.foo<void>
>     <41>   DW_AT_name        : (indirect string, offset: 0xa): foo<int>
>     <49>   DW_AT_name        : (indirect string, offset: 0x0): foo
>     <8f>   DW_AT_name        : (indirect string, offset: 0x87): foo<void>
>     <97>   DW_AT_name        : (indirect string, offset: 0x0): foo
>     8d    	foo<void>
>     3f    	foo<int>
> 
> On Tue, Jul 23, 2019 at 8:35 PM Jim Ingham <jingham at apple.com> wrote:
> lldb can't currently create new template instantiations.  It can only access ones that were generated in the binary you were debugging.  The debug information doesn't have any code, so we can't create new instantiations from there.  Having the debugger try to include headers into the expression context in the same way the compiler did originally is also tricky since we don't know the header search paths or defines that the compiler used when it built the template instantiations...  Raphael has been working on doing this for the case where the C++ code is build into a clang module, but I don't think that work is done yet, and then you have to build your code with modules to use it...
> 
> The <int> expression is failing because clang is being smart and sees that though you mention foo<int> in reference to "test" you never actually use "test", so it doesn't actually have to make that instantiation. In the case where this works with gdb, did you build with clang or did you build with gcc?  If the latter, this might be working for gdb because gcc emits code for the int template instantiation when you mention it, rather than only when you use it?
> 
> Does it also work for gdb when you try:
> 
> (gdb) p sizeof(foo<double>)
> 
> or any other type you haven't mentioned in your code?
> 
> Not that that really matters for what lldb would have to do, but it would be interesting to know...
> 
> Jim
> 
> 
> 
> > On Jul 23, 2019, at 4:22 PM, Scott Funkenhauser via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> > 
> > Hey,
> > 
> > I've noticed that evaluating expressions involving templated classes seems to have some unexpected behavior.
> > 
> > I've created the following sample code to reproduce the issue: 
> > 
> > template <typename T> class foo
> > { 
> >   uint32_t data;
> > };
> > 
> > foo<int> test;
> > 
> > int main() {
> >   foo<void> test2;
> >   return 0;
> > }
> > 
> > I've set a breakpoint on main and evaluated the following expressions:
> > (lldb) p sizeof(foo<void>)
> > (unsigned long) $0 = 4
> > (lldb) p sizeof(foo<int>)
> > error: implicit instantiation of undefined template 'foo<int>'
> > template is declared here
> > 
> > It seems like expression evaluation can only find the specialized templated classes that were used in the current scope. Running the same example using GDB works as expected (both expressions are evaluated correctly).
> > 
> > Is this a known issue?
> > Does anybody have any insight, or familiarity with expression evaluation that would be able to point me in the right direction?
> > 
> > Thanks,
> > Scott
> > _______________________________________________
> > lldb-dev mailing list
> > lldb-dev at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
> 



More information about the lldb-dev mailing list