2013-04-08 9 views
8

Czy istnieje sposób w C++ 11 (przy użyciu najnowszego GCC), aby uzyskać nazwę, lub numer pliku i linii, , metodę nazywającą aktualnie wykonywaną metodę (wywołującą)?Jak uzyskać nazwę lub plik i linię metody dzwoniącego?

Chcę skorzystać z tej informacji w komunikacie o błędzie, gdy na przykład, poniższy kod nie powiedzie się:

void SomewhereInMyProgram() 
{ 
    DoSomething(nullptr); 
} 

void DoSomething(const char* str) 
{ 
    Contract::Requires(str != nullptr); 
    // ... 
} 

Obecnie mam kod w miejscu, które zgłasza błąd jak występujący w DoSomething. Chociaż jest to prawdą techniczną, chciałbym zgłosić błąd występujący w SomewhereInMyProgram w dowolnym miejscu. To ułatwiłoby mi życie!

Rozwiązanie może korzystać z dowolnych funkcji C++ 11, makr lub GCC, ale raczej nie jest to coś, co muszę dodać na każdej stronie wywołania.

Myślę, że stacktrace będzie nie mi pomóc, ponieważ nie mogę używać obsługi wyjątków. Właściwie jestem bardzo ograniczony: jest to środowisko wolnostojące, w którym standardowe nagłówki C++ nie są dostępne. Miałem nadzieję na jakieś makro rozwiązanie.


class Contract 
{ 
public: 
    static void RequiresImpl(bool condition, const char* expression, 
     const char* file, int line); 

    #define Requires(condition) RequiresImpl(condition, #condition , \ 
     __FILE__, __LINE__) 
}; 
+3

Wygląda na to, że szukasz ścieżki stosu w środowisku wykonawczym, tzn. Spójrz na to pytanie SO (w jaki sposób uzyskują stos śledzenia) http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace- when-my-gcc-c-app-crashes – epatel

+0

@epatel Nie jestem ** nie ** szukając stosu, ponieważ nie mogę używać wyjątków. Nawiasem mówiąc, z pewnością nie zadaję tego samego pytania, które zaznaczyłeś duplikatem? – Virtlink

+0

Chodziło mi o to, że powinieneś zajrzeć do funkcji 'handler()', aby sprawdzić, w jaki sposób uzyskuje się tam ślad stosu, tj. Funkcje 'backtrace()', 'backtrace_symbols()' i 'backtrace_symbols_fd()'. Spróbuj użyć ich w tym samym miejscu, w którym chcesz uzyskać "dzwoniącego" – epatel

Odpowiedz

1

Zgodnie z moją najlepszą wiedzą, jedynym sposobem, aby automatycznie uzyskać informacje na temat wcześniejszych połączeń jest użycie ślad. Ten wpis nie zawiera mnóstwo informacji o spowoduje, że:

How to generate a stacktrace when my gcc C++ app crashes

+0

Po przeczytaniu twoich dodatkowych wymagań, myślę, że będziesz musiał użyć czegoś takiego: http://stackoverflow.com/questions/5081123/how- kod dodawania-do-wejścia-każdej-funkcji – krowe

5

Wrap doSomething w makro:

void DoSomethingImp(char const *, char const *file, char const *line) 
{ 
    // do whatever needed, use file and line to report problems 
} 

#define DoSomething(x) DoSomethingImp(x, __FILE__, __LINE__) 

ZASTRZEŻENIE:

To nie jest najlepszą rzeczą do zrobienia, ludzie krzyczą na makra WIN API zdefiniowane w ten sposób dla ANSI lub UNICODE. Uważam jednak, że jest to jedyny sposób, jeśli nie chcesz zmieniać każdego połączenia z DoSomething.

-2

W gcc można użyć jednego z następujących makr: __PRETTY_FUNCTION__ lub __FUNCTION__ lub .

+0

Podaje nazwę aktualnej funkcji, a nie nazwę lub numer linii funkcji wywołującej. – ShreevatsaR

+0

Masz rację. Zły odczytałem pytanie. – Amartel

Powiązane problemy