0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 19
1

Не работает перехват исключений try catch в GCC

15.10.2020, 17:11. Показов 2588. Ответов 29

Из блока try catch вызывается процедура proc в которой возникают разного вида исключения, но ни одно из них не перехватывается этим блоком.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
long double res; 
 
 try 
  {
    res = proc(); 
  }
 catch (...) 
 {
 
 }
 
 
long double proc();
{
 
  long double res,x;
  int32 n;
  long double ve[10];
 
 
  x=1.123;
  n = 5;
 
/*
 В процедуре могут возникать различные исключения,например,
 деление на ноль: 
    res = x/sin(x-x); 
    res = n/(n-5);
 
 переполнение:
   res = pow(x,x*1000);
 
 неверная операция:
   res = pow(-x,x);
 
 ошибка доступа:
   res = x+ve[20]; 
*/
 return res;
}
Ни одно из этих исключений не перехватываются в try , catch и приводят к аварийному завершению программы.
Что я делаю не так?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.10.2020, 17:11
Ответы с готовыми решениями:

не работает перехват исключений
В программе идет подключение к базе intebase через SqlConnect (sqlflat). SqlConnect находиться в...

Не работает обработка исключений Try Catch для Convert.ToInt32("123.4a")
подскажите почему не срабатывает исключение, не какой реакции почему Imports System.Exception ...

Обработка исключений try catch
Здравствуйте. Программа с использованием CLR. Суть работы очень проста - в три TextBox'а вводятся...

Gcc и обработка исключений
Есть пустой проект, компилируемый через QtCreator с gcc 4.9.2, под Дебиан. В него добавляется...

29
6565 / 4550 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
15.10.2020, 17:25 2
Цитата Сообщение от Dmanx Посмотреть сообщение
Ни одно из этих исключений не перехватываются в try , catch и приводят к аварийному завершению программы.
Что я делаю не так?
В gcc, в линуксе, это не исключения, их так не отловишь.
Это сигналы https://www.gnu.org/software/l... dling.html
0
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 19
15.10.2020, 17:46  [ТС] 3
Быстро не понятно. По-моему они занимаются созданием лишних сущностей.
Должно быть всё просто.


На Дельфи подобный код выглядит так:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
var
   E: Exception;
   ErrorCode,E_ZeroDivide,E_InvalidOp,E_OverFlow,E_AccessViolation: Integer;
 
 try
   res:=proc;
 except
   on E: EZeroDivide       do ErrorCode:=E_ZeroDivide;
   on E: EInvalidOp         do ErrorCode:=E_InvalidOp;
   on E: EOverFlow         do ErrorCode:=E_OverFlow;
   on E: EAccessViolation do ErrorCode:=E_AccessViolation;
 end;
Всё просто, понятно и работает.
Как сделать тоже самое , но в GCC?
0
6565 / 4550 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
15.10.2020, 17:55 4
Цитата Сообщение от Dmanx Посмотреть сообщение
Всё просто, понятно и работает.
Как сделать тоже самое , но в GCC?
Никак

Добавлено через 58 секунд
https://habr.com/ru/post/280304/

Добавлено через 3 минуты
https://stackoverflow.com/ques... mingw-sjlj
0
686 / 298 / 97
Регистрация: 04.07.2014
Сообщений: 834
15.10.2020, 18:41 5
За исключением того, что деление целого на ноль UB, остальное вполне (+/-) ловится

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <cmath>
#include <fenv.h>
#include <iostream>
#include <stdint.h>
#include <vector>
 
#pragma STDC FENV_ACCESS on
 
void check_error()
{
    if (math_errhandling & MATH_ERRNO) {
        if (errno == EDOM) printf("errno set to EDOM\n");
        if (errno == ERANGE) printf("errno set to ERANGE\n");
    }
    if (math_errhandling & MATH_ERREXCEPT) {
        if (fetestexcept(FE_INVALID)) printf("FE_INVALID raised\n");
        if (fetestexcept(FE_DIVBYZERO)) printf("FE_DIVBYZERO raised\n");
        if (fetestexcept(FE_OVERFLOW)) printf("FE_OVERFLOW raised\n");
        if (fetestexcept(FE_UNDERFLOW)) printf("FE_UNDERFLOW raised\n");
        feclearexcept(FE_ALL_EXCEPT);
    }
}
 
 
long double proc()
{
 
    long double              res, x;
    int32_t                  n;
    std::vector<long double> ve(10);
 
 
    x = 1.123;
    n = 5;
 
    std::cout << "В процедуре могут возникать различные исключения,например, "
                 "деление на ноль:\n";
 
    res = x / sin(x - x);
    std::cout << res << std::endl;
    check_error();
 
    //    res = n / (n - 5);
    //    std::cout << res << std::endl;
 
    std::cout << "переполнение:\n";
    res = pow(x, x * 1000000);  // fix
    std::cout << res << std::endl;
    check_error();
 
    std::cout << "неверная операция:\n";
    res = pow(-x, x);
    std::cout << res << std::endl;
    check_error();
 
    try {
        std::cout << "ошибка доступа:\n";
        res = x + ve.at(20);
        std::cout << res << std::endl;
    }
    catch (...) {
        std::cout << "Error\n";
    }
 
    return res;
}
 
int main()
{
    (void)proc();
 
    return 0;
}
1
С чаем беда...
Эксперт CЭксперт С++
9989 / 5341 / 1461
Регистрация: 18.10.2014
Сообщений: 12,854
15.10.2020, 19:11 6
Цитата Сообщение от Dmanx Посмотреть сообщение
Из блока try catch вызывается процедура proc в которой возникают разного вида исключения
Никаких исключений в вашей proc нет. Исключения в С++ - это то, что вы сами выбрасываете через throw. Некоторые свойства языка тоже могут выбрасывать исключения, но в вашей функции proc ничего подобного нет. Хотите исключения - делайте throw. Самостоятельно.
0
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 19
15.10.2020, 21:30  [ТС] 7
"Никаких исключений в вашей proc нет."
Какая разница, как назвать: ошибки, исключения,исключительные ситуации,прерывания по ошибке,...Не в названии суть.
Конструкция, которая предназначена перехватывать ошибки не работает.
В Дельфи же, аналогичная - ловит все, что в неё летит, просто и без проблем.
А в С/С++, как всегда, без танцов с бубном не обойтись.
0
С чаем беда...
Эксперт CЭксперт С++
9989 / 5341 / 1461
Регистрация: 18.10.2014
Сообщений: 12,854
15.10.2020, 21:45 8
Цитата Сообщение от Dmanx Посмотреть сообщение
Никаких исключений в вашей proc нет."
Какая разница, как назвать: ошибки, исключения,исключительные ситуации,прерывания по ошибке,...Не в названии суть.
Суть именно в названии. То есть в терминологии. Конструкция try/catch перезватывает исключения. И чтобы понимать, что именно она перехватывает, нужно знать, что такое исключение.

Цитата Сообщение от Dmanx Посмотреть сообщение
Конструкция, которая предназначена перехватывать ошибки не работает.
Нет, никакой "конструкции, предназначенной перехватывать ошибки" в природе не существует, ни в одном языке программирования.

Или может она вам еще и на ошибки в логике программы должна указывать? Вставляете в код "try/catch", а оно вам тут же пишет "Евлампий, согласно техзаданию от Марфы Порфирьевны из бухгалтерского отдела, в месяце апреле должно быть 32 дня. А у вас получается 29".

А раз не указывает - значит "не работает", так?

Цитата Сообщение от Dmanx Посмотреть сообщение
В Дельфи же, аналогичная - ловит все, что в неё летит, просто и без проблем.
А в С/С++, как всегда, без танцов с бубном не обойтись.
Сравнение теплого с мягким.
0
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 19
15.10.2020, 21:53  [ТС] 9
"Сравнение теплого с мягким."
Хорошо. Ну тогда приведите пример "мягкого" кода на С/С++, аналогичный тому, что я привёл в Дельфи.
С таким же алгоритмом работы. Мне всего лишь нужно перехват исключений FPU, AccessViolation и целочисленного деления на ноль во внешней процедуре - proc(). А как называться будет такая конструкция не важно.
А то пока, всё сводится к очень "жёстким" конструкциям, не удобным в использовании.
0
Эксперт С++
8719 / 4262 / 950
Регистрация: 15.11.2014
Сообщений: 9,669
15.10.2020, 22:06 10
Цитата Сообщение от Dmanx Посмотреть сообщение
Какая разница, как назвать: ошибки, исключения,исключительные ситуации,прерывания по ошибке,...Не в названии суть.
Конструкция, которая предназначена перехватывать ошибки не работает.
суть в том, что в твоей программе нет конструкции,
которая предназначена перехватывать ошибки.

ты думаешь что она у тебя есть, а её у тебя нет.
и вообще, в с++ даже понятия такого нет: "перехват ошибки"

вот эта штука:
Цитата Сообщение от Dmanx Посмотреть сообщение
try
работает только с эксепшенами языка с++,
которая не имеет никакого отношения к seh, сигналам, или чему то подобному.
(почти не имеет)

Цитата Сообщение от Dmanx Посмотреть сообщение
В Дельфи же, аналогичная
твоя проблема в том, что ты пытаешься писать на с++,
но мыслишь при этом категорями дельфина.

хорошая новость в том, что если ты - счастливый обладатель компилятора от Visual Studio,
то при желании ты можешь смастерить механизм,
который будет радовать тебя как дельфи.

например, я в работе использую вот такую штуку:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
long double proc()
{
    long double res, x;
    int32_t n;
    long double ve[10];
 
    x = 1.123;
    n = 5;
 
    // В процедуре могут возникать различные исключения,например,
    // деление на ноль: 
    res = x / sin(x - x);
    res = n / (n - 5);
 
    // переполнение:
    res = pow(x, x * 1000);
 
    // неверная операция:
    res = pow(-x, x);
 
    // ошибка доступа:
    res = x + ve[20];
 
    return res;
}
 
TEST_COMPONENT(011)
{
    me::guard guard;
    try 
    {
        proc();
    }
    catch (const ::std::exception& e) 
    {
        (void)e;
        dprint(::std::cerr << "std::exception: " <<  e.what() << "\n");
    }
}
output:
std::exception: INT_DIVIDE_BY_ZERO at address 0x00007FF72431098C (C:/home... test-800-others/test-800-others.exe loaded at base address 0x00007FF7242C0000)

вся магия содержится в классе tools::guard

этот страж умеет перехватывать seh-exception,
и ретранслировать его в виде std::exception.

но нужно понимать, что seh ничего не гарантирует.
в твоей функции proc мой страж смог поймать только деление на ноль.
0
6565 / 4550 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
15.10.2020, 22:20 11
Цитата Сообщение от Dmanx Посмотреть сообщение
Хорошо. Ну тогда приведите пример "мягкого" кода на С/С++, аналогичный тому, что я привёл в Дельфи.
С таким же алгоритмом работы. Мне всего лишь нужно перехват исключений FPU, AccessViolation и целочисленного деления на ноль во внешней процедуре - proc(). А как называться будет такая конструкция не важно.
Это всё SEH-исключения Windows. Visual C++ и Delphi преобразовывают их в обычные исключения, которые можно отловить при помощи try-catch. GCC/MinGW - нет (хотя, возможно, там есть опции компилятора, чтоб тоже преобразовывал).
0
16082 / 8684 / 2120
Регистрация: 30.01.2014
Сообщений: 14,969
16.10.2020, 01:22 12
Dmanx,
Не отрабатывает try catch в VSC2017
Защитит ли конструкция try/catch от взлома программы путем переполнения?

Цитата Сообщение от Dmanx Посмотреть сообщение
А в С/С++, как всегда, без танцов с бубном не обойтись.
Бубен нужен, только если вы делаете что-то противоестественное. Сам по себе дизайн, где по умолчанию в одну кучу собраны и логические исключения и аппаратно-системные, нельзя назвать удачным. Так что удобство, которое дает делфи, на самом деле играет злую шутку с вашим кодом.
0
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 19
16.10.2020, 13:13  [ТС] 13
" Так что удобство, которое дает делфи, на самом деле играет злую шутку с вашим кодом."
Я так и не понял, в чём зло?
Все исключения перехватываются в одном месте через прерывания. Очень удобно, коротко и ясно.
В случае ошибки программа не закрывается аварийно. Полный контроль и информация о ходе работы программы,...
Мне нравится это зло, оно очень полезно.
В GCC,MSVC я так и не понял, как осуществить подобное. Все решения, которые предлагаются либо не работают, либо очень громоздкие и медленные. В случае исключения, программа аварийно завершается, это недопустимо! В Дельфи вы можете хоть тысячу раз вызывать эти ошибки в программе, аварийного завершения не будет. Всё перехватывается.
А Вы можете привести пример перехвата этих исключений в C/С++ , чтоб он работал также как в Дельфи?
И ещё, как запретить программе в C/C++ аварийно закрываться в случае таких ошибок?
0
С чаем беда...
Эксперт CЭксперт С++
9989 / 5341 / 1461
Регистрация: 18.10.2014
Сообщений: 12,854
16.10.2020, 13:19 14
Цитата Сообщение от Dmanx Посмотреть сообщение
" Так что удобство, которое дает делфи, на самом деле играет злую шутку с вашим кодом."
Я так и не понял, в чём зло?
Все исключения перехватываются в одном месте через прерывания. Очень удобно, коротко и ясно.
В случае ошибки программа не закрывается аварийно. Полный контроль и информация о ходе работы программы,...
Мне нравится это зло, оно очень полезно.
Оно очень удобно, но наносит гигантский удар по размеру и эффективности генерируемого кода. Получается так, что исключения могут вылетать практически отовсюду, а не только там, где стоит явный throw. Цена такого "удобства" огромна.

Именно поэтому механизм конверсии SEH исключений в С++ исключений в MSVC++ требует указания специальных ключей компиляции с пониманием того факта, что тем самым вы возможно существенно гробите производительность своего кода.

А в Делфи она просто уже угроблена заранее.
0
16082 / 8684 / 2120
Регистрация: 30.01.2014
Сообщений: 14,969
16.10.2020, 13:27 15
Цитата Сообщение от Dmanx Посмотреть сообщение
Я так и не понял, в чём зло?
Зло в том, что вы под видом обработки "исключений" получаете видимость корректного хода выполнения программы. Вроде бы - "раз я исключение поймал, значит все хорошо". Однако это не так! Часть тех ситуаций, который приводят к SEH (которые оборачивает Delphi в свои исключения) просто в принципе не могут гарантировать нормального хода выполнения программы. Т.е. любые действия в программе после возникновения такого SEH могут привести к непредсказуемым последствиям. А то, что это все обработалось как бы штатно, в общем try блоке, не создает нужного акцента на том, что это критическая ошибка, продолжать работу после которой нельзя.

И видно, что этот факт привел вас к ложной мысли, что в Delphi, дескать, все очень просто, а в C++ - "опять какие-то костыли". Однако это совершенно не так. В Delphi все еще сложнее, т.к. в Delphi этот аспект нужно просто знать и специально разделять варианты действительно исключительных ситуаций и варианты программных ошибок. В С++ by design эти вещи уже разделены, чтобы не создавать иллюзий. Если хотите в С++ как-то обрабатывать программные ошибки, то делайте это отдельно от штатной логики программы.
0
зомбяк
1562 / 1211 / 344
Регистрация: 14.05.2017
Сообщений: 3,925
16.10.2020, 13:32 16
Цитата Сообщение от Dmanx Посмотреть сообщение
Полный контроль и информация о ходе работы программы
Цитата Сообщение от Dmanx Посмотреть сообщение
я так и не понял, как осуществить подобное
1) различайте исключения языка С++ и SEH-исключения операционной системы Windows . Если в делфи оно перемешано это не значит, что и здесь так же. В линуксе SEH-исключений вовсе нет, там идут сигналы операционной системы.
2) Вам дали два примера, как либо использовать встроенный в С++ механизм вычленения ошибок математических вычислений ( https://en.cppreference.com/w/... testexcept ) либо транслирования SEH-исключений в обычные (но это будет работать только под виндой)
3) Зачем писать код, который в обычной ситуации должен вываливаться? Обработка исключений - очень затратная и медленная операция, намного более медленная чем простые условные переходы при обнаружении недопустимых данных.
0
16082 / 8684 / 2120
Регистрация: 30.01.2014
Сообщений: 14,969
16.10.2020, 13:32 17
Цитата Сообщение от Dmanx Посмотреть сообщение
В случае исключения, программа аварийно завершается, это недопустимо!
Если "исключение" - это на самом деле программная ошибка, то вы с этим ничего не сделаете. А в Delphi вам необходимо было бы принудительно аварийно завершиться после этого. Если вы этого не сделаете, то в некоторых ситуациях просто получите мину замедленного действия. Иллюзию работоспособности. Это и есть зло: когды вы думаете, что все хорошо, а на самом деле программа портит данные, например.
0
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 19
16.10.2020, 13:39  [ТС] 18
"А то, что это все обработалось как бы штатно, в общем try блоке, не создает нужного акцента на том, что это критическая ошибка, продолжать работу после которой нельзя."
Вообще, это называется: прятать свои ошибки под ковёр (под блок try except). Это недопустимо. В любом случае, программа выдаёт информацию об ошибке, а не тихо её гасит. А дальше уже полная ответственность на программисте, что с этим делать.
Да, именно так:
"в Delphi этот аспект нужно просто знать и специально разделять варианты действительно исключительных ситуаций и варианты программных ошибок."
Так что, всё равно этот вариант гораздо удобнее.

Я чётко знаю, в каких случаях возникают эти исключения у меня в программе и что с ними делать. Эти исключения должны перехватываться и выдаваться сообщения с конкретной информацией о них, а не аварийно завершаться. При аварийном завершении вы вообще не знаете, где и в чём возникла проблема и не можете легко её устранить.

"Если хотите в С++ как-то обрабатывать программные ошибки, то делайте это отдельно от штатной логики программы."
А как это сделать в моём случае? Я так и не понял.
0
6565 / 4550 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
16.10.2020, 13:44 19
Цитата Сообщение от Dmanx Посмотреть сообщение
"Если хотите в С++ как-то обрабатывать программные ошибки, то делайте это отдельно от штатной логики программы."
А как это сделать в моём случае? Я так и не понял.
Просто проверяй на ноль перед делением, на nullptr перед обращением к указателю и т.д. И делай throw, если ошибка. Поверь, так будет намного лучше. Программа будет читабельнее и надёжнее.
0
16082 / 8684 / 2120
Регистрация: 30.01.2014
Сообщений: 14,969
16.10.2020, 13:45 20
Цитата Сообщение от Dmanx Посмотреть сообщение
А как это сделать в моём случае? Я так и не понял.
На MSVC = использовать ключевые слова __try __except __finally.
Подробная информация и пример есть тут: https://docs.microsoft.com/ru-... ew=vs-2019
На GCC = обработку сигналов. https://pubs.opengroup.org/onl... nal.h.html
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.10.2020, 13:45
Помогаю со студенческими работами здесь

try, throw, catch...обработка исключений
помогите разобраться с обработкой исключений...при вводе пароля больше 10 символов должна быть...

Один catch для нескольих исключений
У меня есть функция, которая бросает исключения, если выполняется условие. Эту функцию я вызываю в...

Обработка исключений Конструкция try.catch.finally
Добрые день, помогите пожалуйста Вводится время в текстбоксе(например 22:23) и в отдельном...

Отлов исключений без использования try/catch
Всем привет. Есть форма и не сколько кнопок. При нажатии на каждой из кнопок будет вызвано...

try catch в методе класса, обработка исключений
Доброго времени суток! Есть задание реализовать Очередь, с обработчиком исключений. Сама очередь...

Перехват ошибок try-catch
В общем, нужно перехватить ошибки, через try-catch, как я понимаю, в моем случае, ошибка возможна...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru