2013-11-20 15 views
5

Może być tak, że trudność, którą mam w opisywaniu mojego problemu, powoduje, że nie mogę znaleźć nikogo innego z jego przykładem. Używam gdb 7.4-2012.04.Dlaczego gdb nie może evaulate funkcji, gdy! =/== i &&/|| są połączone w wyrażeniu?

Wygląda na to, że każde wyrażenie obejmujące zarówno! =/==, jak i & &/|| dla wektorów lub iteratory wektor nie uda się ocenić w gdb z powodu następującego błędu:

nie można uzyskać dostępu do pamięci pod adresem 0x0

Oto przypadek testowy, po mojej linii kompilacji i testów:

#include <stdio.h> 
#include <iostream> 
#include <stdint.h> 
#include <vector> 

using namespace std; 

typedef char GUID[32]; 

int main(int argc, char **argv){ 
    vector<int> vec; 
    for (int i=0; i<5; i++){ 
     vec.push_back(i); 
    } 
    for (vector<int>::iterator vecIter=vec.begin(); vecIter!=vec.end(); vecIter++){ 
     int i=0;//Just need a line gdb will recognize for a breakpoint. 
    } 
    cout << vec[0] << endl;//g++ needs to include operator[] in the binary for this to work. 
    return 0; 
} 

Oto fragment wykonanych przeze mnie testów:

[email protected]$ g++ -g -O0 any_test.cpp 
[email protected]$ gdb a.out 
(gdb) b 16 
(gdb) r 
Breakpoint 1, main (argc=1, argv=0x7fffffffe288) at any_test.cpp:16 
16   int i=0;//Just need a line gdb will recognize for a breakpoint. 
(gdb) p *vecIter == vec[1] or *vecIter == vec[2] 
Cannot access memory at address 0x0 

Oryginalne użyteczne stwierdzenie nie działa. Zredukujmy trochę i znajdźmy problem.

(gdb) p vec[1] or *vecIter == vec[2] 
Cannot access memory at address 0x0 
(gdb) p vec[1] or *vecIter 
$1 = true 
(gdb) p 1 or *vecIter == vec[2] 
Cannot access memory at address 0x0 

Wygląda na to, że problem polega na "==" po "lub". Czy to samo dotyczy innych operatorów?

(gdb) p 1 and *vecIter == vec[2] 
Cannot access memory at address 0x0 
(gdb) p 1 and *vecIter != vec[2] 
Cannot access memory at address 0x0 

To brzmi tak. Co się stanie, jeśli wyciągnę wszystkie funkcje dla gdb? Po prostu niech to dereference i porównać ints?

(gdb) p 1 or *vecIter._M_current == vec._M_impl._M_start[1] 
$2 = true 

Ok, niech sprawdzić pewne kombinacje derefs i funkcji, aby upewnić się, że nie jest po prostu jednym z tych typów, które powoduje problem:

(gdb) p 1 or *vecIter._M_current == *vecIter 
Cannot access memory at address 0x0 
(gdb) p 1 or vec._M_impl._M_start[1] == vec[1] 
Cannot access memory at address 0x0 

Jak widać, problem nie jest konkretnie wektor lub jego iterator. Dowolny operator (funkcja) wywoływana na jednym z nich wywoła ten problem, jeśli zostanie wstawiony po & &/||, a po obu stronach == /! =.

EDYCJA: ponownie zapomniałem o pytaniu. Moje pytanie brzmi: Dlaczego otrzymuję komunikat "Nie mogę uzyskać dostępu do pamięci pod adresem 0x0" w wierszu "p * vecIter == vec [1] lub * vecIter == vec [2]"?

+0

Proszę dać mi znać, jeśli powyższe informacje są niewystarczające, aby odtworzyć określone zachowanie. – longbowrocks

+0

"p * vecIter == vec [1] lub 1" działa. Ale nie "p 1 lub * vecIter == vec [1]" wygląda jak błąd :) – Renjith

+0

Nie jestem pewien, na czym polega problem, ale mogę go odtworzyć z GDB 7.8 na 64-bitowym RHEL 5. Bug? –

Odpowiedz

3

Problem dotyczy funkcji zwracających odwołania. Oto minimalny przykład:

int& g() { static int i; return i; } 
int main() {} 

Ten sam problem jest wystawiony (używam gdb 7.8.1):

(gdb) p 0 || +g() 
Cannot access memory at address 0x0 

Rozwiązaniem jest przekształcenie odniesienie do wskaźnika i pośrednie to:

(gdb) p 0 || +*&g() 
$1 = true 

Zapisano błąd: https://sourceware.org/bugzilla/show_bug.cgi?id=17904

0

Kolejność oceniania "* vecIter == vec [1]" oznacza ocenę * vecIter first, jeśli true, pomiń ocenianie vec [1], a całe wyrażenie jest prawdziwe; a jeśli false, przetestuj vec [1]. Główną przyczyną jest to, że vecIter wskazuje na pamięć NULL, która jest niedostępna, że ​​* vecIter nie może nawet zostać oceniony. Dlatego gdb wydrukuje błąd "dostęp do pamięci".

Powód dla innych instrukcji drukowania o tym samym błędzie

+0

Co sprawia, że ​​mówisz "vecIter" wskazuje na pustą pamięć? – OJFord