Thread View: pl.comp.os.linux.programowanie
9 messages
9 total messages
Started by heby
Wed, 09 Sep 2020 07:16
EINTR - sztuczne generowanie
Author: heby
Date: Wed, 09 Sep 2020 07:16
Date: Wed, 09 Sep 2020 07:16
12 lines
1598 bytes
1598 bytes
Cześć. Potrzebuję w celach testowych zasypać aplikację errorami EINTR. Aplikacja robi bardzo duzo operacji read/write i w ten sposób chciałbym zwiększyśc prawdopodobieństwo znalezienia miejsca bez obsługi EINTR. Mam pid mojego procesu. W jaki sposób mogę spowodować że w procesie tym znacząco zwiększy się ilośc EINTR w przypadkowych miejscach? Rozumiem że mam wysyłać sygnały do mojego procesu. Można to zrobic za pomocą kill? I jaki sygnał mam wysyłać? Dowolny? np SIGCONT albo SIGALRM będzie ok?
Re: EINTR - sztuczne generowanie
Author: Mateusz Viste
Date: Wed, 09 Sep 2020 08:18
Date: Wed, 09 Sep 2020 08:18
35 lines
1950 bytes
1950 bytes
2020-09-09 o 09:16 +0200, heby napisał:
> Potrzebuję w celach testowych zasypać aplikację errorami EINTR.
> Aplikacja robi bardzo duzo operacji read/write i w ten sposób
> chciałbym zwiększyśc prawdopodobieństwo znalezienia miejsca bez
> obsługi EINTR.
>
> Mam pid mojego procesu. W jaki sposób mogę spowodować że w procesie
> tym znacząco zwiększy się ilośc EINTR w przypadkowych miejscach?
>
> Rozumiem że mam wysyłać sygnały do mojego procesu. Można to zrobic za
> pomocą kill? I jaki sygnał mam wysyłać? Dowolny? np SIGCONT albo
> SIGALRM będzie ok?
To byłoby pewnie dobre, gdybyś chciał testować funkcje read(), write(),
send(), itp na okoliczność poprawnej obsługi sygnałów. Tobie jednak
zależy raczej na sprawdzeniu swojego własnego kodu, który jest klientem
tych funkcji. Ja zrobiłbym to tak:
ssize_t monkey_write(int fd, const void *buf, size_t cnt) {
static int crazy_monkey;
crazy_monkey ^= 1;
if (crazy_monkey == 0) {
errno = EINTR;
return(-1);
}
return(write(fd, buf, cnt));
}
#define write monkey_write
(tutaj dalszy kod programu)
Mateusz
Re: EINTR - sztuczne generowanie
Author: heby
Date: Wed, 09 Sep 2020 08:53
Date: Wed, 09 Sep 2020 08:53
10 lines
1717 bytes
1717 bytes
On 09/09/2020 10:18, Mateusz Viste wrote:
> To byłoby pewnie dobre, gdybyś chciał testować funkcje read(), write(),
> send(), itp na okoliczność poprawnej obsługi sygnałów. Tobie jednak
> zależy raczej na sprawdzeniu swojego własnego kodu, który jest klientem
> tych funkcji. Ja zrobiłbym to tak:
> ssize_t monkey_write(int fd, const void *buf, size_t cnt) {
Wchodzi to w grę, ale wymaga ingerencji w kod. Ja zaś myślę nad
*automatyzacją* zagadnienia na testach tak, aby sprawdzić nie tylko mój
kod, ale i kod biblitek 3rd party na które nie mam do końca wpływu.
Re: EINTR - sztuczne generowanie
Author: Mateusz Viste
Date: Wed, 09 Sep 2020 09:02
Date: Wed, 09 Sep 2020 09:02
21 lines
1896 bytes
1896 bytes
2020-09-09 o 10:53 +0200, heby napisał:
> On 09/09/2020 10:18, Mateusz Viste wrote:
> > To byłoby pewnie dobre, gdybyś chciał testować funkcje read(),
> > write(), send(), itp na okoliczność poprawnej obsługi sygnałów.
> > Tobie jednak zależy raczej na sprawdzeniu swojego własnego kodu,
> > który jest klientem tych funkcji. Ja zrobiłbym to tak:
> > ssize_t monkey_write(int fd, const void *buf, size_t cnt) {
>
> Wchodzi to w grę, ale wymaga ingerencji w kod.
Niekoniecznie. Tzn. tak - wersja z monkey_write na pewno, ale można
wystrugać alternatywę w postaci własnej wersji write(), do wpięcia
podczas link time, zastępując tym samym read/write z libc. Ew.
podstawić swoje własne, zhackowane libc.
Opcja z kill oczywiście też wydaje się koszerna, ale trzeba będzie tym
killem ostro naparzać, żeby mieć szansę trafić w okienko kiedy
aplikacja akurat próbuje coś czytać/pisać... Niektóre krótkie operacje
mogą nigdy nie trafić w sygnał.
Mateusz
Re: EINTR - sztuczne generowanie
Author: Queequeg
Date: Wed, 09 Sep 2020 10:03
Date: Wed, 09 Sep 2020 10:03
18 lines
1518 bytes
1518 bytes
Mateusz Viste <mateusz@xyz.invalid> wrote:
> ssize_t monkey_write(int fd, const void *buf, size_t cnt) {
> static int crazy_monkey;
Hmm, jesteś pewien, że statyczne, ale lokalne zmienne, są inicjalizowane
na 0?
Zawsze myślałem, że dotyczy to tylko globalnych zmiennych statycznych, ale
teraz czytam i w sumie już nie wiem.
--
Jeśli będziesz tak lotny jak pszczółka
Tak silny jak niedźwiedź
Jeśli będziesz pracował jak koń
I do domu wracał tak zmęczony jak pies
Wtedy musisz pójść do weterynarza
Bo być może stałeś się już OSLEM.
Re: EINTR - sztuczne generowanie
Author: heby
Date: Wed, 09 Sep 2020 10:04
Date: Wed, 09 Sep 2020 10:04
12 lines
1711 bytes
1711 bytes
On 09/09/2020 11:02, Mateusz Viste wrote: > killem ostro naparzać, żeby mieć szansę trafić w okienko kiedy > aplikacja akurat próbuje coś czytać/pisać... Niektóre krótkie operacje > mogą nigdy nie trafić w sygnał. Przy dziesiątkach tysięcy testów/h non-stop takie "przypadki" pojawiają się nadspodziewanie często i mają jednocześnie brzydką cechę niewystepowania in vitro, kiedy podpinasz debugger. Chcę takie narzędzie do naparzania EINTR po to, aby: a) złapać je na testach b) przyspieszyć łapanie lokalne, z debugiem.
Re: EINTR - sztuczne generowanie
Author: Mateusz Viste
Date: Wed, 09 Sep 2020 11:27
Date: Wed, 09 Sep 2020 11:27
28 lines
1748 bytes
1748 bytes
2020-09-09 o 10:03 +0000, Queequeg napisał:
> Mateusz Viste <mateusz@xyz.invalid> wrote:
>
> > ssize_t monkey_write(int fd, const void *buf, size_t cnt) {
> > static int crazy_monkey;
>
> Hmm, jesteś pewien, że statyczne, ale lokalne zmienne, są
> inicjalizowane na 0?
Tak.
> Zawsze myślałem, że dotyczy to tylko globalnych zmiennych
> statycznych, ale teraz czytam i w sumie już nie wiem.
Może w tych nowoczesnych wynalazkach z plusami coś się zmieniło, nie
wiem. Ja żyję w 1990 i dobrze mi tu.
ISO/IEC 9899:1990(E), rozdział 6.5.7:
"If an object that has static storage duration is not initialized
explicitly, it is initialized implicitly as if every member that has
arithmetic type were assigned 0 and every member that has pointer type
were assigned a null pointer constant."
Żadnych udziwnień typu "tak, ale tylko jeśli..." nie widzę.
Mateusz
Re: EINTR - sztuczne generowanie
Author: Queequeg
Date: Thu, 10 Sep 2020 10:00
Date: Thu, 10 Sep 2020 10:00
14 lines
1494 bytes
1494 bytes
Mateusz Viste <mateusz@xyz.invalid> wrote: > Może w tych nowoczesnych wynalazkach z plusami coś się zmieniło, Raczej nie, moje niedopatrzenie. W sumie bardzo rzadko używam static storage. -- Zając dowiedział się że jego synowi ktoś w knajpie wybił wszystkie zęby. Wchodzi do knajpy i mówi: - Kto mojemu synowi wybił wszystkie żeby? Wstaje niedźwiedź: - Ja! Bo co? - Ano, chciałem się spytać gdzie można znaleźć dobrego dentystę...
Re: EINTR - sztuczne generowanie
Author: michal.lyszczek
Date: Tue, 20 Oct 2020 00:54
Date: Tue, 20 Oct 2020 00:54
62 lines
3517 bytes
3517 bytes
On 2020-09-09 12:04:00, heby wrote:
> On 09/09/2020 11:02, Mateusz Viste wrote:
> > killem ostro naparzać, żeby mieć szansę trafić w okienko kiedy
> > aplikacja akurat próbuje coś czytać/pisać... Niektóre krótkie operacje
> > mogą nigdy nie trafić w sygnał.
>
> Przy dziesiątkach tysięcy testów/h non-stop takie "przypadki" pojawiają się
> nadspodziewanie często i mają jednocześnie brzydką cechę niewystepowania in
> vitro, kiedy podpinasz debugger.
>
> Chcę takie narzędzie do naparzania EINTR po to, aby:
> a) złapać je na testach
> b) przyspieszyć łapanie lokalne, z debugiem.
Do takich rzeczy najlepiej zrobić sobie MOCKi. W C najprościej zrobić to
pisząc sobie osobną libkę np libmockread.so, i w kodzie libki zdefiniować
sobie symbol read() (z takimi samymi argumentami jak read(2)) i potem
wziąć wskaźnik na swojego stuba read() oraz wrapera z glibc read(2).
Np. coś takiego
void *g_real_function = dlsym(RTLD_NEXT, read);
/* mock funkcji read - przykryje ona read(2) z glibc */
ssize_t read(int a0, void *a1, size_t a2) {
if (g_no_error) {
ssize_t (*real)(int, void *, size_t);
real = g_real_function;
return real(a0, a1, a2);
}
errno = EINTR;
return (ssize_t)-1;
}
Potem skompilować libkę
gcc -shared -fPIC -Wl,-soname,readmock.1 -o libreadmock.so readmock.c -lc -ldl
i zrobić preload na końcu
LD_PRELOAD=./libreadmock.so ./unit-tests
W unit testach można sobie potem ustawiać g_no_error na 1 albo 0 w zależności
czy chcemy aby następny read(2) wywalił błąd.
<shameless-plug>
Też kiedyś stałem przed takim problemem aż w końcu napisałem sobie generator
co mi tworzy odpowiedni plik C z potrzebnymi mockami oraz prostym API
do konfigurowania kiedy i jaki błąd ma wystąpić (np EINTR dokładnie po 4
wywołaniu read(2)). A co najważniejsze, przy takim podejściu mozna testować
nie robiąć jakichkolwiek zmian w kodzie produkcyjnym
Program/libkę znajdziesz tutaj:
https://libfo.bofc.pl/index.html
https://git.bofc.pl/libfo/
</shameless-plug>
--
.-----------------.-------------------.---------------------.------------------.
| Michal Lyszczek | Embedded C, Linux | Company Address | .-. open source |
| +48 727 564 419 | Software Engineer | Leszczynskiego 4/29 | oo| supporter |
| https://bofc.pl `----.--------------: 50-078 Wroclaw, Pol | /`'\ & |
| GPG FF1EBFE7E3A974B1 | Bits of Code | NIP: 813 349 58 78 |(\_;/) programer |
`----------------------^--------------^---------------------^------------------'
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads