namhyung / uftrace

Function graph tracer for C/C++/Rust/Python
https://uftrace.github.io/slide/
GNU General Public License v2.0
3.04k stars 473 forks source link

Detecting function arguments from its C++ demangled symbol name #295

Open honggyukim opened 6 years ago

honggyukim commented 6 years ago

Since C++ symbols contain arguments information, I think it'd be useful if we can detect function arguments based on its C++ function symbol name.

For example, QString::fromLatin1_helper is shown as QString::fromLatin1_helper(char const*, int) in the below trace. (--demangle=full is enabled)

# DURATION     TID     FUNCTION
            [  1071] | _GLOBAL__sub_I_qqmldebugconnection.cpp() {
            [  1071] |   __static_initialization_and_destruction_0(int, int) {
   9.777 us [  1071] |     QString::fromLatin1_helper(char const*, int);
   0.121 us [  1071] |     __cxa_atexit();
   0.147 us [  1071] |     QString::fromLatin1_helper(char const*, int);
   0.050 us [  1071] |     __cxa_atexit();
  11.302 us [  1071] |   } /* __static_initialization_and_destruction_0(int, int) */
  11.918 us [  1071] | } /* _GLOBAL__sub_I_qqmldebugconnection.cpp */
            [  1071] | main(1, 0x7ffe044491f8) {
            [  1071] |   QmlProfilerApplication::QmlProfilerApplication(int&, char**) {
 136.747 us [  1071] |     QCoreApplication::QCoreApplication(int&, char**, int);
   0.206 us [  1071] |     QString::fromLatin1_helper(char const*, int);
            [  1071] |     QQmlDebugConnection::QQmlDebugConnection(QObject*) {
   0.134 us [  1071] |       operator new(unsigned long);

In this case, we can extract QString::fromLatin1_helper(char const*, int) function's argument types and use them as follows:

# DURATION     TID     FUNCTION
            [  1327] | _GLOBAL__sub_I_qqmldebugconnection.cpp() {
            [  1327] |   __static_initialization_and_destruction_0(1, 65535) {
   6.496 us [  1327] |     QString::fromLatin1_helper("QDeclarativeDebugServer", 23);
   0.172 us [  1327] |     __cxa_atexit();
   0.184 us [  1327] |     QString::fromLatin1_helper("QDeclarativeDebugClient", 23);
   0.043 us [  1327] |     __cxa_atexit();
   8.857 us [  1327] |   } /* __static_initialization_and_destruction_0 */
   9.340 us [  1327] | } /* _GLOBAL__sub_I_qqmldebugconnection.cpp */
            [  1327] | main(1, 0x7ffe9137d8f8) {
            [  1327] |   QmlProfilerApplication::QmlProfilerApplication() {
 138.249 us [  1327] |     QCoreApplication::QCoreApplication();
   0.417 us [  1327] |     QString::fromLatin1_helper("127.0.0.1", 9);
            [  1327] |     QQmlDebugConnection::QQmlDebugConnection() {
   0.087 us [  1327] |       operator new();

This method can be limited somehow, but would be useful in many cases although we need to check if the type extract can be done correctly as well.

namhyung commented 6 years ago

I'm not sure about the quality of the demangler - an incorrect type parsing could result in a crash due to (string) pointer dereferences.

honggyukim commented 6 years ago

I thought that we can use this only in limited primitive types.