2009-08-25 7 views
33

Mentalnie, zawsze zastanawiałem się, jak try/throw/catch wygląda za kulisami, kiedy kompilacje C++ tłumaczą je na asembler. Ale ponieważ nigdy go nie używam, nigdy nie zdążyłem go sprawdzić (niektórzy ludzie powiedzieliby leniwie).C++ try/throw/catch => kod maszynowy

Czy normalny stos jest używany do śledzenia try s, czy też oddzielny stos wątków jest przechowywany tylko w tym celu? Czy implementacja MSVC i g ++ jest duża czy mała? Proszę pokazać mi pseudo asm (IA-32 też jest w porządku), więc nigdy nie muszę sam tego sprawdzać! :)

Edytuj: Teraz otrzymuję podstawy implementacji MSVC na obsłudze IA-32. Ktoś wie na g ++ na IA-32, czy jakikolwiek inny procesor?

Odpowiedz

7

Microsoft Journal „pod maską” serii zrobił wygląd pogłębione na to bardzo przedmiotem w 1997 roku:

A Crash Course on the Depths of Win32™ Structured Exception Handling

+0

Dotyczy to obsługi strukturalnej wyjątków systemu Windows, która jest związana z obsługą wyjątku C++, ale nie jest taka sama.Pietrek wspomina we wstępie, że wyjątki C++, implementowane przez Microsoft i Borland, używają SEH, ale jego artykuł nie obejmuje * jak * go implementują. –

+0

Świetny artykuł MSVC/IA-32, choć długi. –

+1

Wyjątki C++ to tylko klasa wyjątków SEH, z opakowaniem zawierającym informacje C++ (klasa wyjątków). Wyjątki C++ muszą używać SEH, aby rozprzestrzeniać granice jądra, itp. –

15

Jest to bardzo cenny artykuł na ten temat: How a C++ compiler implements exception handling

+1

Ten artykuł został opublikowany w 2002 roku ... czy jest naprawdę aktualny? – Klaim

+0

Wziąłem przegląd dawno temu. Nie jestem do końca pewien, czy jest aktualny. – AraK

+13

2002 jest dość aktualny według standardów C++ – Javier

0

Wystarczy popatrzeć na this document który opisuje wewnętrzne wyjątku obsługi całkiem dobrze.

18

Słabe implementacje obsługi wyjątków wcisnąć jakiś wyjątek bloku obsługi dla każdej próby na stosie środowiska wykonawczego, gdy wprowadzono klauzulę "wypróbuj", i wyślij ją, gdy kończy się klauzula "wypróbuj". Zostanie również zachowana lokalizacja zawierająca adres ostatnio wstawionego bloku obsługi wyjątków. Zazwyczaj te procedury obsługi wyjątków są powiązane razem, więc można je znaleźć, podążając za linkami od najnowszych do starszych wersji. Gdy wystąpi wyjątek, zostanie znaleziony wskaźnik do ostatnio wstawionego bloku obsługi EH i sprawdzane jest przetwarzanie tego przypadku EH w klauzuli "próbuj". Uderzenie w przypadku EH powoduje, że porządek w stosie następuje z powrotem do punktu wciśniętego EH, a sterowanie przechodzi do przypadku EH. Brak trafień w EH powoduje znalezienie następnego EH, a proces się powtarza. 32-bitowy system SEH dla systemu Windows jest wersją tego.

Jest to słaba implementacja, ponieważ program płaci cenę runtime za każdą klauzulę try (push, pop), nawet jeśli nie wystąpi żaden wyjątek.

Dobre implementacje po prostu rejestrują tabelę zakresów, w których występują klauzule try. Oznacza to, że istnieje zero narzutów, aby wejść/wyjść z klauzuli try. (My PARLANSE programowanie parangell langauge używa tej techniki). Wyjątek wyszukuje komputer PC punktu wyjątku w tabeli i przekazuje kontrolę do EH wybranego przez tabelę. Kod EH resetuje stos stosownie do potrzeb. Szybko i ładnie. Myślę, że 64-bitowy system Windows EH jest tego typu, ale nie przyjrzałem się uważnie.

3

Standardowa komisja C++ opublikowała raport techniczny na temat "wydajności C++", aby obalić wiele mitów o tym, jak funkcje C++ rzekomo spowalniają. Obejmuje to również szczegóły dotyczące sposobu obsługi wyjątków. The draft tego raportu technicznego jest dostępny za darmo. Sprawdź punkt 5.4.1. "Wyjątek w obsłudze problemów i technik implementacji".