2013-02-05 11 views
6

Program mój rzuca std::out_of_range. Znam powód, że mam dostęp do wektora z indeksem -1 gdzieś. To, czego nie wiem, to nazwa wektora (nazwa zmiennej) i lokalizacja w kodzie. Komunikat o błędzie produkowane przez mój program wygląda następująco:Znajdź obiekt do rzucania std :: out_of_range

terminate called after throwing an instance of 'std::out_of_range' 
    what(): vector::_M_range_check 
zsh: abort (core dumped) ./main.x config.cfg 

natomiast komunikat o błędzie produkowanego przez kod jakiegoś innego faceta (on używa g++ zbyt) i publikowane w pytaniu C++ accessing vector wygląda następująco:

Error for vec.at(i).setVec(tmp); 
Error is: terminate called after throwing an instance of 'std::out_of_range' 
    what(): vector::_M_range_check 

Tzn. powiedziano mu nazwę zmiennej. Moje pytanie brzmi:

Czy jest jakiś sposób, aby powiedzieć g++/gcc, aby podać mi rozszerzone informacje? Może nawet zawierać numery linii (nie wiem, czy to możliwe, ale hej, facet może śnić;)).
Po prostu dla funs uruchomiłem mój program w opcji gdb z opcją catch thrown (mogę dodać, mam prawie zerowe doświadczenie w używaniu rzeczywistego debuggera), który nie powiedział mi nic nowego, w rzeczywistości, to nie powiedział mi błąd wynika z wyjątku std::out_of_range.

Btw, moje flagi kompilatora (do debugowania) są:

CFLAGS = --exceptions -I$(ROOTSYS)/include --std=c++11 -Wall -g -O0 -fno-inline -fno-eliminate-unused-debug-types 
+9

Po uruchomieniu 'gdb' z' catch throw', gdy wyjątek zostanie przechwycony, wpisz 'where'. –

+0

@DavidSchwartz Perfect! Więc teraz mam numery linii z 'gdb', jakąkolwiek szansę na uzyskanie drugiego komunikatu o błędzie (tj. Nazwy bez debuggera)? – elemakil

Odpowiedz

3

Po naciśnięciu klawisza przerwania, wprowadź polecenie bt (śledzenie) w powłoce gdb. Spowoduje to wydrukowanie śledzenia stosu (sekwencji wywołań funkcji prowadzących do błędu).

Aby uzyskać nazwę zmiennej, można teraz użyć polecenia up, aby nawigować w górę stosu i sprawdzić, które zmienne są używane w każdej z tych funkcji.

+0

Działa to zgodnie z oczekiwaniami, po przejściu na szczyt stosu (tj. Wielu komend 'up') drukowana jest linia z błędnym kodem. – elemakil

3

umieścić punkt przerwania na std::out_of_range::out_of_range. Obiekt wyjątku, podobnie jak wszystkie obiekty C++, rozpoczyna swoją żywotność po zakończeniu konstruktora.

[EDIT] Komentarz był jasny: problem z ciągiem produkowanym przez std::out_of_range::what(). To jest zdefiniowane w ramach implementacji. Oczywiście w twoim przypadku składa się z __FUNCTION__, makra GCC, które nazywa bieżącą (to znaczy rzucającą) funkcję. Ale taka funkcja zna tylko wskaźnik do bieżącego obiektu, a nie jego nazwę. W drugim przypadku nazwa obiektu jest pobierana inną metodą, a nie inną.

+0

Zakładam, że masz na myśli, że wykonuję 'break std :: out_of_range :: out_of_range' w' gdb' przed uruchomieniem aplikacji (np. Polecenie 'run'). Tylko zrobienie tego ma taki sam efekt jak "catch throw", a więc wydawanie 'where' po osiągnięciu punktu przerwania (zgodnie z sugestią @DavidSchwartz) pokazuje numer linii. Jednak podobnie jak jego rozwiązanie wymaga użycia debuggera, prawda? Oznacza to, że drugi komunikat o błędzie nie może zostać osiągnięty przy użyciu tej metody. – elemakil

+0

Zakładam, że nie ma prostego sposobu na dodanie funkcjonalności drukowania nazwy obiektu? – elemakil

+0

@elemakil: Nie, o to chodzi. Funkcja, która rzuca _does_ zna "ten" wskaźnik do obiektu i jego własną nazwę funkcji, ale nie nazwę obiektu. (Pomijając filozoficzne pytanie, czym jest nazwa obiektu, zależy to zwykle od tego, jak głęboko znajdujesz się w tym stoliku). – MSalters

Powiązane problemy