Debugging a Qt application in Visual Studio and checking opaque objects (e.g. QDir or QFileInfo)

I am debugging a Qt application in Visual Studio 2013. I have the official Visual Studio plugin from Qt. I can see the contents of a QString , but for any other QObject , such as a QDir or QFileInfo , I cannot see it.

Am I doing something wrong or is it simply impossible?

When I expand the QDir instance, I can only see an element named d_ptr that refers to a QDirPrivate object that I cannot verify. I also cannot call other QDir or QFileInfo , such as path() or filePath() at runtime from the debugger. When I try, Visual Studio claims that the address of the function has been optimized.

Is there any need to debug this without adding dozens of log statements to the program?

+5
source share
1 answer

UPDATE

After a detailed description of the last answer that this was not possible, today I found a way to make the debugger display closed (hidden) information.

Note. I keep the previous post below, because it reveals the whole path that I followed to reach this solution, and I think it is worth keeping track of the mistakes made and the wrong conclusions, so no one has drawn them again;).

Suppose you have a variable QDir d; . You can check its internal data by making a manual throw in the Clock window:

 (Qt5Cored.dll!QDirPrivate*)d.d_ptr.d 

View window

Unfortunately, it does not show any useful information, since you will encounter the same problem for internal members (private data is not printed).

However, from now on, you can now modify your .natvis file to display the necessary data on hover:

 <?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="QDir"> <DisplayString>path={((Qt5Cored.dll!QDirPrivate*)d_ptr.d)-&gt;dirEntry.m_filePath}</DisplayString> </Type> </AutoVisualizer> 

done!

I could not print this information in the Watch window (if I add the Expand section to the .natvis file, it seems to be omitted), but at least you have this debug time information.

I suggest you look at the personal header files or the Watch window (as described at the beginning of the answer) for the types you want to check so that you can add the correct data to the .natvis file.

What was wrong with the previous analysis?

I think the key point is manual casting. I mentioned that

dirEntry is part of QDirPrivate , so itโ€™s clear that the debugger cannot check it.

This was partially correct. The problem was that the debugger did not know where to find QDirPrivate , since it is not an exported Qt character; as soon as we specified this explicitly (using (Qt5Cored.dll!QDirPrivate*) cast), he was able to check it.


ORIGINAL RESPONSE

AFAIK is not possible for these classes. Unfortunately, there are some private structures that are not exported and which, it seems, cannot view the debugger.

Note. I work with Qt 5.6.1, so I will use its source code from the qt.io repository to match my examples.

Take, for example, QDir : it is defined in qdir.h , which is part of the Qt public API. In the same file, it declares QDirPrivate , but its full definition is in qtdir_p.h , which is not part of the public API.

Even if characters are loaded, somehow the definition of this class remains obscure to the debugger. See the example below the .natvis file I used:

 <?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="QDir"> <DisplayString>Path: {d_func()-&gt;dirEntry.m_filePath}</DisplayString> </Type> </AutoVisualizer> 

But when trying to view QDir d(qApp->applicationDirPath()); : The debugger shows the following:

Error: class "QDirPrivate" does not have a name "dirEntry"

Error evaluating 'd_func () โ†’ dirEntry.m_filePath'

but dirEntry is part of QDirPrivate , so itโ€™s clear that the debugger cannot check it. dirEntry is of type QFileSystemEntry defined in qfilesystementry_p.h (another private class).

Finally, if you look at the qt5.natvis file from Qt VS Tools and find the corresponding classes in the source code, see that all included classes provide a definition of the structures used by the .natvis file.


UPDATE

The only public API of such classes are methods, unfortunately, the calling functions from the debugger are not supported. Referring to the answer in the MSDN forum from Microsoft Staff :

A function call from the debugger is executed with fire. You will probably encounter interdependence depending on cross-threads (even if you don't have explicit cross-thread dependencies, there are common locks for things like memory allocation). This is why the C ++ debugger does not support implicit funceval.

In fact, if you try to call any method, for example QDir::absolutePath() in the viewport or in the .natvis file, you will see the following error message:

Error: QDir :: absolutePath function has no address, possibly due to compiler optimization.


NOT SO ELEGANT WORK

A possible solution would be to use wrapper classes that store these private values. You will need to replace each object with a shell, but it can help.

Below you will find a very simple example for QDir (you will need to fill in the required constructors and save the necessary information). Keep in mind that this type of class in Qt was designed so that it is not extensible, so there are no virtual methods (so keep in mind redefining some of them and using an object cast from the base class).

 class MyQDir : public QDir { public: MyQDir(const QString& path) : QDir(path) { m_absolutePath = absolutePath(); } private: QString m_absolutePath; }; 

and following the .natvis file to display the MyQDir path:

 <?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="MyQDir"> <DisplayString>Path: {m_absolutePath}</DisplayString> </Type> </AutoVisualizer> 

Finally, I think that the only remaining solution is to print the information to the console ( qDebug() ).


As an additional note, this tutorial explains how to write a custom .natvis file. This is for 2015, but I used it for 2017 flawlessly. I hope this is valid for 2013.

+5
source

Source: https://habr.com/ru/post/1269231/


All Articles