2011-02-08 5 views
7

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

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

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

+3

Я не понимаю ваш вопрос - вы уже размещены ваш собственный ответ, используйте код из binutils. Есть похожие библиотеки/фрагменты кода для других инструментальных цепей, поэтому в чем проблема? –

+3

IIRC then valgrind уже имеет параметр --demangle = yes для демонстрации символов C++ на выходе. Callgrind можно назвать «valgrind --tool = callgrind --demangle = yes», не так ли? –

+0

@ Luther: Я открыл еще один форум, чтобы проверить, не перепутал ли я vallgrind http://stackoverflow.com/questions/4846411/de-mangeling-in-callgrind, но никто не ответил. Я посмотрел на руководство по Linux, чтобы развернуть его, ничего не предоставляя! ваше предложение сработало. thnks –

ответ

13

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

+2

Да, это работает в командной строке. Я считаю, что искатель искал библиотечные функции, которые можно было бы вызвать из кода. – Dave

+0

Это принятый ответ, поэтому я думаю, что он отвечает на вопрос о том, что искал искатель. –

+0

Все хорошо, на самом деле я узнал что-то новое, когда прочитал ваш ответ, поэтому я, безусловно, его ценю. Я добавил версию «из кода» ниже, так как это то, что я искал, основываясь на названии вопроса. Я уверен, что оба ответа помогут кому-то. :) – Dave

11

Вот мой 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; 
} 

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

Вот макрос, который я использую для доступа к названию типа demangled как (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)); 
+0

Неплохо. Мог бы сделать это 'unique_ptr', или просто построить его' std :: string' и free(). – sehe

+0

Спасибо sehe. :) Мне нужно взглянуть на unique_ptr (еще не использовали их). Я намеренно не использовал метод std :: string/немедленный свободный(), чтобы избежать дополнительной копии. Тем не менее, производительность, вероятно, не имеет большого значения - я обычно использую это только для отладочной печати, а не для любого критически важного приложения. Во всяком случае, мы надеемся, что достаточно кого-то, чтобы настроить функцию на свои нужды. – Dave