Невозможно отловить исключения из стекового объекта - PullRequest
1 голос
/ 13 марта 2011

надеюсь, у тебя хороший день.

Я работаю над классом, чтобы обернуть Berkley C Networking API, пока у меня только работает TCP сервер / клиент.

По иронии судьбы у меня проблема не в сети, а в стеке и куче. Возможно, я просто не понимаю это полностью, но когда я использую что-то вроде: ClientSocket *mysock = new ClientSocket(); И просто вызывайте функции с помощью оператора ->, все работает отлично - мой класс SocketException не обнаруживается, если возникает ошибка.

Но когда я использую: ClientSocket mysock; И любые исключения генерируются при вызове функции с использованием. Оператор, это показывает: terminate called after throwing an instance of 'SocketException' Aborted И просто возвращает меня к терминалу.

Забыл добавить, я заключаю вызовы в блоки try / catch.

Мне известно, что в первом примере используется ключевое слово 'new' для возврата указателя на новый экземпляр ClientSocket в куче, а во втором - для стека, но я не знаю проблемы.

Я думаю, что мне чего-то не хватает в указателях / ссылках / стеке / куче, но я понятия не имею, что происходит. Код часто выполняется просто отлично, но если какие-то исключения выдается ....>: (* ​​1016 *

РЕДАКТИРОВАТЬ: на странице ссылок, Client.cxx и Server.cxx являются файлами примеров! Спасибо, что указал на это, Эрик. Помощь с этим будет принята с благодарностью. Источники для этого проекта:
ссылки на все файлы: http://furryhead.co.cc/problem.html
(Я не мог вставить более 2 ссылок, и у меня есть 4 файла, так что это нужно будет делать, пока кто-нибудь не сможет объединить ссылки в моем сообщении) Осторожно: Socket.cxx довольно большой, поскольку содержит определения ServerSocket, ClientSocket и SocketException.

Команды для компиляции всех вышеперечисленных файлов:
g ++ -c Socket.cxx -o Socket.o
g ++ -c Server.cxx -o Server.o
g ++ -c Client.cxx -o Client.o
g ++ Server.o Socket.o -o сервер
g ++ Client.o Socket.o -o клиент

Спасибо!

Небольшое обновление, согласно рекомендации Джона, я просмотрел документы по функциям сокетов, и теперь у него улучшены отчеты об ошибках - я проверяю переменную 'errno' и выкидываю исключение, основанное на этом. (Это, и я не устанавливаю это для неблокирования ...;)) - Просто хотел обновить и сказать спасибо! : D

Ответы [ 2 ]

7 голосов
/ 13 марта 2011

Для меня это звучит как исключение, выдаваемое по уважительной причине, и во время разматывания стека некоторые деструкторы (возможно, ClientSocket?) Бросают.Поскольку среда выполнения не может разрешить эту ситуацию каким-либо осмысленным образом (два исключения «выбрасываются» одновременно), вызывается функция terminate и программа закрывается.

Вопрос без ответа - почему какой-то деструкторбросил бы, если объект, которому он принадлежит, размещен в стеке.Но для ответа на этот вопрос требуется больше данных.Возможно, вы можете копнуть немного глубже и проверить мою гипотезу?

Кстати, если это действительно так, и, поскольку ни один деструктор не должен когда-либо бросать что-нибудь , мы можем заключить, что класс-нарушитель смертельно ущербен.

Обновление : кажется, я был на деньгах.

Деструктор вашего класса Socket вызывает close, а close может бросить.Это серьезная ошибка программирования.Вы должны заключить вызов close в деструктор в

try {
    close();
}
catch(...)
{ /* this space intentionally left blank */ }

, и сбой исчезнет.

Второе обновление (больше не падает)

Если recv возвращает -1, это означает, что сокет находится в неблокирующем режиме, и в настоящее время нет доступных данных для получения.Это не ошибка, а особенность.Вы не должны бросать исключение там.То, что вы должны делать в точности, зависит от того, хотите ли вы использовать сокет в режиме блокировки или неблокирования.

0 голосов
/ 13 марта 2011

Джон уже решил проблему завершения, но в исходном коде есть еще одна проблема.

Причина, по которой динамически размещенный объект, по-видимому, работает, заключается в том, что, когда в другом месте возникает исключение, он протекает и деструктор никогда не вызывается.Хотя это позволяет избежать проблемы двойного исключения, оно вызывает другой набор позже ...

...