2016-12-07 10 views
6

Próbuję znaleźć wszystkie miejsca w dużej i starej bazie kodu, w której wywoływane są określone konstruktory lub funkcje. W szczególności są to określone konstruktory i funkcje składowe klasy std::string (czyli basic_string<char>). Na przykład, załóżmy, że istnieje linia kodu.Jak mogę znaleźć wszystkie miejsca, w których funkcja członkowska lub ctor jest wywoływana w kodzie g ++?

std::string foo(fiddle->faddle(k, 9).snark); 

W tym przykładzie, nie jest oczywiste, patrząc na to, że snark może być char *, czyli to, co mnie interesuje

Próby rozwiązania tego problemu

Sprawdziłem niektóre z funkcji zrzutów gcc i wygenerowałem niektóre z nich, ale nie udało mi się znaleźć żadnych informacji, które wskażą mi, że podana linia kodu będzie wygenerować wywołanie do konstruktora string, biorąc const char *. Skompilowałem także kod z opcją -s, aby zapisać wygenerowany równoważny kod zespołu. Ale to cierpi na dwie rzeczy: nazwy funkcji są "zniekształcone", więc nie można wiedzieć, co nazywa się w C++; i nie ma żadnych numerów linii, więc znalezienie odpowiedniego miejsca w pliku źródłowym byłoby trudne.

Motywacja i tła

W moim projekcie, jesteśmy Porting dużą, starą bazę kodu z systemu HP-UX (i ich ACC C++) na RedHat Linux i gcc/g ++ v.4.8.5 . Łańcuch narzędzi HP umożliwił zainicjowanie wskaźnika string za pomocą wskaźnika NULL, traktując go jako pusty ciąg. Wygenerowany kod narzędzi Gnu kończy się niepowodzeniem z pewnym smakiem błędu dereferencji zerowej. Musimy więc znaleźć wszystkie potencjalne przypadki tego i je naprawić. (Na przykład, dodając kod do sprawdzenia dla NULL i zamiast tego użyj wskaźnika do łańcucha "").

Więc jeśli ktoś tam musiał zmierzyć się z podstawowym problemem i może zaoferować inne sugestie, to również być mile widziane.

+0

wypracować zniekształconej nazwy funkcji, którą próbujesz szukać –

+0

Może mógłbyś zrobić globalnego wyszukiwania i zastąpić zmienić 'std :: string' i' string' do pewnej klasy własną rękę to następnie zarejestruje komunikat, gdy ten konkretny konstruktor zostanie nazwany –

+2

Zmień nazwę funkcji/zmień parametry konstruktora, skompiluj ponownie wszystko i poproś o to kompilator. –

Odpowiedz

0

pierwsze chciałbym utworzyć nagłówek tak:

#include <string> 

class dbg_string : public std::string { 
public: 
    using std::string::string; 
    dbg_string(const char*) = delete; 
}; 

#define string dbg_string 

Następnie zmodyfikować makefile i dodać „-include dbg_string.h” do flagami, aby wymusić to na każdego pliku źródłowego bez modyfikacji.

Można również sprawdzić, jak zdefiniowano NULL na swojej platformie i dodać do niej określone przeciążenie (np. Dbg_string (int)).

+0

To jest bardzo hacky, ale bardzo interesujące i twórcze. – Alex

1

Czy rozważałeś zastosowanie analizy statycznej?

Clang ma jeden zwany analizatorem klang, który można rozszerzyć.

Możesz napisać niestandardową wtyczkę, która sprawdza to konkretne zachowanie, zaimplementując klang ast ast, który wyszukuje deklaracje zmiennych łańcuchowych i sprawdza ustawienie wartości null.

Istnieje instrukcja dla tego here.

Zobacz także: https://github.com/facebook/facebook-clang-plugins/blob/master/analyzer/DanglingDelegateFactFinder.cpp

0

Można spróbować CppDepend i jego CQLinq potężny język zapytań kod do wykrywania gdzie używane są niektóre contructors/metody/pola/typy.

from m in Methods where m.IsUsing ("CClassView.CClassView()") select new { m, m.NbLinesOfCode }