Функция для манипулирования / деманглирования функций

Ранее здесь было показано, что функции C++ трудно представить в сборке. Теперь я заинтересован в том, чтобы прочитать 1, так или иначе, потому что callgrind, часть valgrind, показывает, что они деформированы, в то время как в сборке они отображаются искаженными, поэтому я хотел бы либо манипулировать выходными данными функции valgrind, либо деманглировать имена функций. Кто-нибудь когда-нибудь пробовал что-то подобное? Я искал на сайте и обнаружил следующее:

 Code to implement demangling is part of the GNU Binutils package; 
see libiberty/cplus-dem.c and include/demangle.h.

кто-нибудь когда-нибудь пробовал что-то подобное, я хочу разобрать / калечить в C? мой компилятор gcc 4.x

2 ответа

Решение

Использовать c++filt инструмент командной строки, чтобы разобрать имя.

Вот моя реализация на C++11, созданная на следующей странице: http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html

#include <cxxabi.h>  // needed for abi::__cxa_demangle

std::shared_ptr<char> cppDemangle(const char *abiName)
{
  int status;    
  char *ret = abi::__cxa_demangle(abiName, 0, 0, &status);  

  /* NOTE: must free() the returned char when done with it! */
  std::shared_ptr<char> retval;
  retval.reset( (char *)ret, [](char *mem) { if (mem) free((void*)mem); } );
  return retval;
}

Чтобы упростить управление памятью для возвращаемого значения (char *), я использую std::shared_ptr с пользовательской лямбда-функцией 'deleteter', которая вызывает free() для возвращаемой памяти. Из-за этого мне не нужно беспокоиться об удалении памяти самостоятельно, я просто использую ее по мере необходимости, и когда shared_ptr выходит из области видимости, память освобождается.

Вот макрос, который я использую для доступа к имени demangled type как (const char *). Обратите внимание, что у вас должен быть включен RTTI, чтобы иметь доступ к 'typeid'

#define CLASS_NAME(somePointer) ((const char *) cppDemangle(typeid(*somePointer).name()).get() )

Итак, из класса C++ я могу сказать:

printf("I am inside of a %s\n",CLASS_NAME(this));

Это небольшая вариация версии Дэйва, приведенной выше. Это версия unique_ptr с небольшой проверкой возвращаемого типа, хотя похоже, что вы могли бы просто проигнорировать это, но почему-то это кажется нечистым.

auto cppDemangle (const char *abiName)
{
    //
    // This function allocates and returns storage in ret
    //
    int status;
    char *ret = abi::__cxa_demangle(abiName, 0 /* output buffer */, 0 /* length */, &status);

    auto deallocator = ( [](char *mem) { if (mem) free((void*)mem); } );

    if (status) {
        // 0: The demangling operation succeeded.
        // -1: A memory allocation failure occurred.
        // -2: mangled_name is not a valid name under the C++ ABI mangling rules.
        // -3: One of the arguments is invalid.
        std::unique_ptr<char, decltype(deallocator) > retval(nullptr, deallocator);
    }

    //
    // Create a unique pointer to take ownership of the returned string so it
    // is freed when that pointers goes out of scope
    //
    std::unique_ptr<char, decltype(deallocator) > retval(ret, deallocator);
    return retval;
}
Другие вопросы по тегам