2011-02-08 11 views
7

Poprzednio, here, pokazano, że funkcje C++ nie są łatwo reprezentowane w złożeniu. Teraz jestem zainteresowany czytaniem w ten czy inny sposób, ponieważ callgrind, część valgrind, pokazują, że są demanglowane, podczas gdy w montażu są pokazane jako zniekształcone, więc chciałbym albo zmienić wyjście funkcji valgrind albo zdemontować nazwy zespołów funkcji. Czy ktoś kiedykolwiek próbował czegoś takiego? Szukałem na website i dowiedział się, co następuje:funkcja funkcji mangle/demangle

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

ktokolwiek próbował coś takiego, chcę demangle/magiel w C? moim kompilatorem jest gcc 4.x

+3

Nie rozumiem Twoje pytanie - już wysłane własną odpowiedź, użyj kodu z binutils. Istnieją podobne biblioteki/fragmenty kodu dla innych narzędzi, więc gdzie jest problem? –

+3

IIRC, a następnie valgrind ma już opcję --demangle = yes, aby zdemontować symbole C++ na wyjściu. Callgrind można nazwać jako 'valgrind --tool = callgrind --demangle = yes', czy nie? –

+0

@Luther: Otworzyłem inne forum, aby sprawdzić, czy nie demaskuję vallgrind http://stackoverflow.com/questions/4846411/de-mangeling-in-callgrind, ale nikt nie odpowiedział. Spojrzałem na podręcznik dla Linux-a, żeby go zdemontować, ale niczego nie dostarczył! Twoja sugestia zadziałała. thnks –

Odpowiedz

13

Użyj narzędzia wiersza polecenia c++filt, aby usunąć jego nazwę.

+2

Tak, działa w linii poleceń. Wierzę, że pytający szukał funkcji bibliotecznych, które można było wywołać z poziomu kodu. – Dave

+0

Jest to zaakceptowana odpowiedź, więc myślę, że odpowiada na pytanie o to, czego szukał pytający. –

+0

Wszystko dobrze, w zasadzie nauczyłem się czegoś nowego, kiedy przeczytałem twoją odpowiedź, więc z pewnością to doceniam. Dodałem wersję "z kodu" poniżej, ponieważ to właśnie szukałem na podstawie tytułu pytania. Jestem pewien, że obie odpowiedzi pomogą komuś. :) – Dave

11

Oto mój C++ 11 realizacja, pochodzące z poniższej strony: 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; 
} 

Aby zarządzanie pamięcią łatwo na zwróconej (char *), używam std :: shared_ptr z niestandardową funkcją "deltera" lambda, która wywołuje funkcję free() w zwracanej pamięci. Z tego powodu, nigdy nie muszę się martwić o samodzielne usuwanie pamięci, używam go w razie potrzeby, a gdy shared_ptr wychodzi poza zakres, pamięć zostanie zwolniona.

Oto makro, którego używam, aby uzyskać dostęp do nazwy typu demangled jako (const char *). Należy pamiętać, że trzeba mieć RTTI włączony mieć dostęp do „typeid”

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

Tak więc, od wewnątrz C++ klasa mogę powiedzieć:

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

Nieźle. Mogłoby to zrobić 'unique_ptr' lub po prostu skonstruować' std :: string' of it i free() natychmiast. – sehe

+0

Dzięki sehe. :) Będę musiał rzucić okiem na unique_ptr (jeszcze ich nie używałem). Celowo nie użyłem metody std :: string/direct free(), aby uniknąć dodatkowej kopii. To powiedziawszy, trafienie wydajnościowe prawdopodobnie nie miałoby większego znaczenia - zazwyczaj używam go tylko do debugowania, w przeciwieństwie do wszelkiego rodzaju aplikacji o dużej szybkości. W każdym razie, mam nadzieję, że jest wystarczająco dużo, aby ktoś mógł dostosować funkcję do własnych potrzeb. – Dave

Powiązane problemy