2012-06-27 18 views
6

Generowanie błędu zapisu w pakiecie testowym jest proste, pisząc pod numer /dev/full. Czy istnieje dobra technika generowania błędu odczytu? Obecnie używam LD_PRELOAD do zastąpienia read, ale wydaje się to zbyt skomplikowane i nieprzenośne (nie że/dev/full jest przenośne ...).Generowanie błędu odczytu

+0

Po prostu myśl, ale co powiesz na czytanie z pliku z ustawieniami perms na 000? –

+0

@Loadmaster To spowoduje błąd 'open' zamiast błędu' read'. –

+0

Czy szukasz EINVAL? – jpe

Odpowiedz

5

Oprócz czytania z katalogu (jak wspomniano w poprzedniej odpowiedzi) można spróbować odczytać /proc/self/mem dostać błąd (to powinien dostać ci EIO w systemie Linux). Aby uzyskać wyjaśnienie, zobacz: https://unix.stackexchange.com/a/6302

+0

Dobra sztuczka, ale pamiętaj, że '/ proc/self/mem' jest dobre tylko jeśli czytasz od początku pliku. Jeśli program szuka najpierw, może przypadkowo trafić do strefy zmapowanej. – Gilles

2

Zgodnie z instrukcją (OS X) read (2), read (2) wygeneruje błąd, jeśli "[a] n zostanie podjęta próba odczytania katalogu." Możesz więc otworzyć (2) katalog (upewnij się, że prot nie pozwala na pisanie, a to spowoduje błąd), a następnie spróbuj go odczytać. Wygląda na to, że wymieniony jest jedyny błąd, który może wystąpić w "normalnych" okolicznościach (tj. Bez robienia czegoś takiego, jak celowe złamanie struktury FILE *).

Przypuszczam, że mówisz o błędach odczytu (2) w języku C lub czymś podobnym, ale nawet w języku wyższego poziomu możesz być w stanie otworzyć katalog i spróbować go odczytać (chociaż Po prostu wypróbowałem to w Pythonie i jest zbyt inteligentne, aby otworzyć katalog ...)

1

Równie dobrze można przekazać niedozwolony wskaźnik jako bufor do odczytu, który zwróci wartość -EFAULT. coś takiego:

read(fd, (char *)0, cout); 

Dzięki Suzuki

+0

Nie wygeneruje to błędu odczytu (EINVAL), ale podczas odczytu bufor znajduje się poza dostępną przestrzenią adresową (EFAULT). Ale według człowieka 2 przeczytane powinno być możliwe dotarcie do EINVAL z niewielkimi modyfikacjami. Ale pytanie brzmi: "jak dostać się do EINVAL bez modyfikowania kodu, ale tworzenia opakowania, które będzie emulować wszystkie interesujące sytuacje awaryjne". – jpe

+0

Rzeczywiście kod nie powinien być modyfikowany, a proces musi pomyślnie otworzyć plik, wykonać wiele operacji we/wy (zarówno odczyt, jak i zapis), ale następnie należy wykonać pewne operacje odczytu, aby zakończyć się niepowodzeniem. Można to zrobić przez przesłonięcie odczytu i implementacji prostego licznika, aby operacja N-ta zakończyła się niepowodzeniem, ale byłoby miło zrobić coś ze skryptu powłoki podobnego do: 'kill -STOP $ pid; plik chmod 000; zabić -CONT $ pid'.Metoda otrzymywania błędu zapisu w podobnych warunkach byłaby miła, ponieważ zapis do/dev/full kończy się niepowodzeniem przy pierwszym zapisie. –

4

Podejście, które działa na wszystkich głównych unices byłoby wdrożyć mały system plików FUSE. EIO jest domyślnym kodem błędu, gdy twój sterownik systemu plików przestrzeni użytkownika robi coś złego, więc jest łatwy do osiągnięcia. Oba powiązania: Perl i Python zawierają przykłady, aby rozpocząć, możesz szybko napisać system plików, który w większości odzwierciedla istniejące pliki, ale wstrzykuje EIO w dokładnie wybranych miejscach.

Istnieje taki system plików: petardfs (article), nie wiem, jak dobrze działa po wyjęciu z pudełka.

+0

Och, +1: petardfs jest wyraźnie właściwą rzeczą do zrobienia. –