Buduję wspólną bibliotekę, która wewnętrznie korzysta z Boost.thread. W rezultacie Boost.system jest również używany, ponieważ zależy od tego Boost.thread. Moja udostępniona biblioteka eksportuje interfejs C, więc chcę ukryć całą moją obsługę wyjątków wewnętrznych i użycie wątku itp. Od użytkownika końcowego. To ma być czarna skrzynka. Jednak gdy łączę się z aplikacją kliencką, gdy program działa poprawnie - gdy tylko nadejdzie czas, aby zatrzymać przetwarzanie przez wywołanie funkcji bibliotecznej, otrzymuję:Wewnętrzne wyjątki w bibliotece współdzielonej kończą aplikację użytkownika końcowego.
zakończyć wywołanie po rzuceniu wystąpienia "boost :: thread_interrupted" "
Przechwytuję ten wyjątek wewnętrznie w bibliotece, więc nie mam pojęcia, dlaczego tak naprawdę nie zostanie złapany. Program użytkownika końcowego w żaden sposób nie ma na celu informowania się o wyjątkach funkcji Boost ani o nich nie traktuj. Podczas budowania współużytkowanej biblioteki używam statycznego linkowania zarówno dla Boost.thread, jak i Boost.system, więc świat zewnętrzny nigdy nie jest przeznaczony do ich wyświetlania. Jestem na GCC 4.7 na Ubuntu 12. W Windowsie nie mam takich problemów (ani z MSVC, ani z MinGw).
(EDIT)
Mam pytanie do edycji pokazują minimalistyczny przykład, który reprodukuje problemu, zgodnie z wnioskami w komentarzach.
Tutaj pierwszy kod dla testlib.cpp i testlib.h.
testlib.cpp:
#include <boost/thread/thread.hpp> void thread_func() { while(1) { boost::this_thread::interruption_point(); } } void do_processing() { // Start a thread that will execute the function above. boost::thread worker(thread_func); // We assume the thread started properly for the purposes of this example. // Now let's interrupt the thread. worker.interrupt(); // And now let's wait for it to finish. worker.join(); }
A teraz testlib.h:
#ifndef TESTLIB_H #define TESTLIB_H void do_processing(); #endif
buduję ten w udostępnionej biblioteki za pomocą następującego polecenia:
g ++ -static-libgcc - static -s -DNDEBUG -I/usr/boost_1_54_0 -L/usr/boost_1_54_0/stage/lib -Wall -shared -fPIC -o libtestlib.so testlib.cpp -lboost_thread -lboost_system -lpthread -O3
Wtedy, mam kod trywialny program kliencki, który wygląda następująco:
#include "testlib.h" #include <cstdio> int main() { do_processing(); printf("Execution completed properly.\n"); return 0; }
zbudować klienta w następujący sposób:
g ++ -DNDEBUG -I/usr/boost_1_54_0 -L ./ -Wall -o client.cpp klient -ltestlib -O3
Kiedy uruchomić klienta, otrzymuję:
terminate nazywany po wrzuceniu instancją 'boost :: thread_interrupted'
Przerwano (core dumped)
Nie zauważam wyjątku wyjątku przerwania wątku, ale zgodnie z dokumentacją Boost Boost.thread robi to i kończy tylko dany wątek. Próbowałem jawnie wychwycić wyjątek z wewnątrz funkcji thread_func, ale to nie miało znaczenia.
(koniec edycji)
(EDIT 2)
Warto zauważyć, że nawet z -fexceptions włączona, problem nadal występuje.Próbowałem także rzucić i złapać wyjątek zdefiniowany w tej samej jednostce tłumaczeniowej, co kod, który ją przechwytuje i wyrzuca, bez żadnej poprawy. Krótko mówiąc, wszystkie wyjątki wydają się pozostawać niezabezpieczone we wspólnej bibliotece, mimo że zdecydowanie mam dla nich obsługę przechwytywania. Kiedy kompiluję plik klienta i plik testlib jako część pojedynczego programu, to znaczy bez tworzenia testlib do współużytkowanej biblioteki, wszystko działa zgodnie z oczekiwaniami.
(koniec EDIT 2)
Wszelkie wskazówki?
Proponuję wykonać *** minimalny test ***, który demonstruje problem (pomyśl o 5-liniowym pliku Makefile). Połóż to na github/gist. Możliwe, że znajdziesz przyczynę/obejście tego procesu. Jeśli nie, faktycznie będziesz miał coś, co nam pokaże. – sehe
@ komentarze takie jak to powinno być nieskończenie wznawiane, szczególnie w przypadku "Są szanse, znajdziesz przyczynę/obejście w procesie". Niezliczone są czasy, w których zacząłem zadawać pytanie na temat SO, aby znaleźć rozwiązanie, próbując zdobyć minimalną ilość kodu reprodukcyjnego. – stijn
@stijn Wiem. Szczerze mówiąc, powiedziałem to tylko dlatego, że dosłownie nie mamy innej opcji, poza dziką zgadywanką, jak jest teraz. Naprawdę chcę w tym pomóc, ale nie ma co dalej. – sehe