getting LLDB to follow pointers to templates - c++

I am trying to follow pointers to templates on LLDB. I keep failing, as in (names changed to protect the guilty):
> (lldb) expr *(p->q->r)
(x::y) $5 = {
x::z<t::u> = {
...
> (lldb) expr p->q->r->x::z<t::u>
error: 'x::z' is not a member of class 'x::y'
(lldb)
There's got to be a way to do it, since the Clion IDE (using LLDB as its debugger) lets me click on such links as deeply as they go, template or no template. So how is this done in bare LLDB?
(yes, I looked high&low for documentation)

Related

Is it possible to remove gdb aliases without restarting gdb?

Suppose I define a new gdb command which includes an alias.
import gdb
import string
class PrettyPrintString (gdb.Command):
"Command to print strings with a mix of ascii and hex."
def __init__(self):
super (PrettyPrintString, self).__init__("ascii-print",
gdb.COMMAND_DATA,
gdb.COMPLETE_EXPRESSION, True)
gdb.execute("alias -a pp = ascii-print", True)
Now, I'd like to make a small change to the script and source it again in the same gdb session. Unfortunately, when I try to source again, I get the following error.
gdb.error: Alias already exists: pp
How can I delete the original alias and source the updated script?
Note that the alias documentation does not appear to say anything about deleting aliases, and I tried unalias and delete but neither had the desired effect.
You can define a keyword to a function instead of as an alias. For example I have
define w
where
end
in my .gdbinit. And re-defining works, as opposed to re-aliasing.

Qt Creator not working with GDB Pretty Printing

I'm attempting to use Qt Creator to develop on Unreal Engine 4 in Linux. I've run into an issue with the debugger: I'm unable to get Qt Creator to use GDB's pretty printers.
Epic has written pretty printers for their custom containers (like their string class) and these work great in GDB. From Qt Creator's Debugger Log, I can see that GDB is registering these printers. In fact, I can even enter a "print " command and the output is formatted nicely. However, entering the variable as an expression in the watch window, all I see is the memory address the FString points at.
Specifically, here is the debugger command issued and the resulting output when I add the FString variable "Filename" to the watch window:
Command:
140python theDumper.fetchVariables({"autoderef":1,"context":"","displaystringlimit":"100","dyntype":1,"expanded":["local","watch","inspect","local.Filename.Data","local.Filename","return"],"fancy":1,"formats":{},"nativemixed":0,"partialvar":"watch.0","passexceptions":0,"qobjectnames":0,"resultvarname":"","stringcutoff":"10000","token":140,"typeformats":{},"watchers":[{"exp":"46696c656e616d65","iname":"watch.0"}]})
<Rebuild Watchmodel 16 # 09:05:19.576 [54836ms] >
Output:
dADJUSTING CHILD EXPECTATION FOR local.Filename
dADJUSTING CHILD EXPECTATION FOR local.Filename.Data
<140python theDumper.fetchVariables({"autoderef":1,"context":"","displaystringlimit":"100","dyntype":1,"expanded":["local","watch","inspect","local.Filename.Data","local.Filename","return"],"fancy":1,"formats":{},"nativemixed":0,"partialvar":"watch.0","passexceptions":0,"qobjectnames":0,"resultvarname":"","stringcutoff":"10000","token":140,"typeformats":{},"watchers":[{"exp":"46696c656e616d65","iname":"watch.0"}]})
>&"python theDumper.fetchVariables({\"autoderef\":1,\"context\":\"\",\"displaystringlimit\":\"100\",\"dyntype\":1,\"expanded\":[\"local\",\"watch\",\"inspect\",\"local.Filename.Data\",\"local.Filename\",\"return\"],\"fancy\":1,\"formats\":{},\"nativemixed\":0,\"partialvar\":\"watch.0\",\"passexceptions\":0,\"qobjectnames\":0,\"resultvarname\":\"\",\"stringcutoff\":\"10000\",\"token\":140,\"typeformats\":{},\"watchers\":[{\"exp\":\"46696c656e616d65\",\"iname\":\"watch.0\"}]})\n"
>~"data=[{iname=\"watch.0\",name=\"0\",numchild=\"0\",valueencoded=\"notaccessible\",value=\"\",},{iname=\"watch.0\",wname=\"46696c656e616d65\",numchild=\"1\",type=\"FString &\",value=\"\",address=\"0x7fffffff76b8\",},],typeinfo=[],partial=\"1\"\n"
>~"\"[{'d_d_ptr': 3, 'cannotBeQObject': 3}, [['locals', 117], ['watches', 837842], ['safePrint', 54]]]\"\n"
>140^done
<Rebuild Watchmodel 16 # 09:05:19.576 [54836ms] >
sFinished retrieving data
(Not sure if the "ADJUSTING CHILD EXPECTATION FOR" lines were for the previous command or this one)
Toggling the "Load system GDB pretty printers" option doesn't seem to have any effect.
Searching the web hasn't yielded much for me so far. Any help would be greatly appreciated!
Edit: oh this is interesting. I did a diff of the output with pretty printing disabled vs enabled. With it enabled, I get:
<23importPlainDumpers on
sStopped at breakpoint 1 (1) in thread 1.
<24-thread-info
>&"importPlainDumpers on\n"
>&"Python Exception <type 'exceptions.AttributeError'> 'function' object has no attribute 'subprinters': \n"
>&"Error occurred in Python command: 'function' object has no attribute 'subprinters'\n"
>23^error,msg="Error occurred in Python command: 'function' object has no attribute 'subprinters'"
Edit 2: Looking into it more, it appears Qt Creator may not support pretty printers that involve using lookup functions. Is this the case?
Okay. It appears Qt Creator expects pretty printers to conform to the structure defined by the PrettyPrinter and SubPrettyPrinter objects, and enforced by the register_pretty_printer() function, defined in gdb's printing.py script and documented here: https://sourceware.org/gdb/onlinedocs/gdb/gdb_002eprinting.html
Unreal's printers do not do this.
However, even if they did, it appears Qt Creator's import code will only import subprinters, not parent pretty printers (refer to importPlainDumpers() in gdbbridge.py). It seems the best way to solve this is to update Unreal's printers to follow the examples I can find of using a function to build 'RegexpCollectionPrettyPrinter's.

lldb: conditional breakpoint on a most derived type

typical debugging pattern:
class Button : public MyBaseViewClass
{
...
};
....
void MyBaseViewClass::Resized()
{
//<---- here I want to stop in case MyBaseViewClass is really a Button, but not a ScrollBar, Checkbox or something else. I.e. I want a breakpoint condition on a dynamic (most derived) type
}
trivial approaches like a breakpoint on strstr(typeid(*this).name(), "Button") don't work because on typeid lldb console tells:
(lldb) p typeid(*this)
error: you need to include <typeinfo> before using the 'typeid' operator
error: 1 errors parsing expression
surely #include in console before making the call doesn't help
You can do this in Python pretty easily. Set the breakpoint - say it is breakpoint 1 - then do:
(lldb) break command add -s python 1
Enter your Python command(s). Type 'DONE' to end.
def function (frame, bp_loc, internal_dict):
"""frame: the lldb.SBFrame for the location at which you stopped
bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
internal_dict: an LLDB support object not to be used"""
this_value = frame.FindVariable("this", lldb.eDynamicDontRunTarget)
this_type = this_value.GetType().GetPointeeType().GetName()
if this_type == "YourClassNameHere":
return True
return False
DONE
The only tricky bit here is that when calling FindVariable I passed lldb.eDynamicDontRunTarget which told lldb to fetch the "dynamic" type of the variable, as opposed to the static type. As an aside, I could have also used lldb.eDynamicRunTarget but I happen to know lldb doesn't have to run the target go get C++ dynamic types.
This way of solving the problem is nice in that you don't have to have used RTTI for it to work (though then we'll only be able to get the type of classes that have some virtual method - since we use the vtable to do this magic.) It will also be faster than a method that requires running code in the debugee as your expression would have to do.
BTW, if you like this trick, you can also put the breakpoint code into a python function in some python file (just copy the def above), then use:
(lldb) command script import my_functions.py
(lldb) breakpoint command add -F my_functions.function
so you don't have to keep retyping it.

IDE doesn't recognize the method

I'm trying to acces the cityMethod() inside the class City.
class City
{
void cityMethod() { }
}
So, I do:
map<string,City> mymap;
City c;
mymap["Madrid"] = c;
Now, when I do this:
mymap["Madrid"].cityMethod();
Ok, it works. But the IDE(Qt) doesn't recognize the "cityMethod".
Am I doing something wrong? Is that compiler issue?
This feature does not seem to be supported by Qt Creator. There's an open issue about it on http://bugreports.qt.io/.
It does work when using the ClangCodeModel plugin though. To use it, go to Help > About Plugins and activate the plugin there:
Then, enable its use in the options. Tools > Options > C++ > Code Model
You might experience performance issues with the Clang code model, but it does work:

Automatically show properties of C++ objects in Xcode debugger

The Xcode debug area can sometimes show a summary of the most important variables inside of an object that's in the list, without the need to expand the object to see it's individual members.
Is there a way for me to teach the debugger about my own C++ objects to do the same? Let's say I have a simple class with a single member variable:
class Foo
{
int bar;
};
And the debug area should show something like the following:
aVariableOfTypeFoo = (Foo) bar=123
I know that some C++ objects are able to do this (for example std::vector shows it's size), but I wasn't able to figure out if this is somehow configurable, or if it's built-in in the debugger/Xcode itself.
I'm using Xcode 5.0.1
Thanks
You can change the summary description for a given type selecting Edit Summary Format... by right clicking on a variable of that type.
The format in your case is pretty simple and will look like this: bar = {$VAR.bar}
For more information about formats check the "Using Data Formatters" section in the Xcode User Guide (pages 42 & 43).