Как отловить segmentation fault с помощью try/catch ?
В Windows я просто выставляю опцию и ловлю, если ли такое же в Linux? Пишу на C++.
В Linux нет аналога SEH. Можно отловить сегфолт через signal(SIGSEGV) , а уже из обработчика кинуть плюсовое исключение.
Посоны, а для чего ловить сегфолт с помощью try/catch ?
смотрел. не помогло.
Есть ошибка не могу найти — сложный код. А быстренько обойти её, было бы временным решением.
handle SIGSEGV ignore в GDB. Правда, он в 100% заглючит и зациклится, например.
быстренько обойти её, было бы временным решением..
Ох, что сейчас тут начнётся.
Рефакторинг уровня дворник.
и как этот «handle SIGSEGV ignore в GDB» сделать?
надо сдать через час )))
— какой курс?
— 6000
Только в void handler(int) бросаеш исключение.
Если тебе надо ловить сегфолт через исключение, то, скорее всего, ты что-то абсолютнейшим образом делаешь неправильно.
1) GDB
2) Valgrind
3) Strace
4) fprintf(stderr, «Я не лох, Торвальдс тоже принтами советует дебажить код»);
segmentation fault моя самая любимая ошибка, ее ловить очень просто — логами и\или коркой
хуже если не падает и работает иногда плохо — вот тут можно и день потратить, а найти потом какойто забытый if )
Особенно хорошо ловить коркой наведенный сегфолт, когда кто то проехалтся по заголовку std::vector а потом ты в него через хрен знает сколько инструкций полез и оно уппало. И смотришь такой на gdb указывающего в потроха stl в полном недоумении.
Еще стек может порушиться или попортиться немного ранее того места, где упадет в корку. Бэктрейс тоже может стать непонятным тогда. Впрочем, valgrind немного помогает проследить за стеком.
Маленькие радости плюсового программиста. Я, с тех пор как на Rust перешёл, ловлю сегфолты только во внутренностях графических драйверов (написанных на C++, надо полагать).
С говнокодерами побоку, не может сегфолтнуться — будет висеть и не отвечать на внешние воздействия.
Вот зачем ты это сделал, а? Я глянул вики — мне прямо понравилось. ;-(
А нет, глянул перегрузку операций в обобщенных типах (так чтоли оно у них, ну аналог шаблонов, типажи растовские) — разонравилось. Слишком много букв;-)
Правда там какие то макросы есть продвинутые с регэкспами.
Зато в gdb всего 3 буквы.
Ну gdb я не так часто пользуюсь.
Есть точно так же генерик и есть специализация. В чем больше буков то?
В синстаксисе? Но это субъективно.
Еще одна проблема — как раст дружит с кудой? Плюсовый код (без извращений) переносится почти 1:1.
Тут скорее вопрос, кого поддерживает cuda, а не кто её.
Можно отловить сегфолт через signal(SIGSEGV), а уже из обработчика кинуть плюсовое исключение.
Можешь подробнее расписать. Потому что я не догоняю, как обработчик исключения, выброшенного из обработчика сигнала, догадается откуда на самом деле его хотели выбросить (из того участка кода, который привел к SIGSEGV). Ведь для обработки исключения нужен правильный EIP и ESP.
Как передать информацию из обработчика сигнала, чтобы исключение реально вышло из кода, который вызвал SIGSEGV я тоже не догоняю. Про то, что это можно сделать мегахаками на очень низком уровне — я в курсе. Я хочу понять, как можно
уже из обработчика кинуть плюсовое исключение.
Никак. Можно заюзать sigaction и внутри обработчика раскрутить стектрейс.
Можно список написанных тобою несегфолтящихся программ на расте?
Нельзя. А что заставило тебя подумать, что я пишу на Rust? Хотя нет, не отвечай.
Ты уже несколько лет в каждом десятом треде свою растоклоунаду разводишь. Она могла быть убедительнее, будь она подкреплена доказательствами.
В этом треде о Rust начал говорить не я.
Меня устраивает уровень ее убедительности.
а уже из обработчика кинуть плюсовое исключение
Нельзя. Компилятор не ожидает исключение на каждой инструкции, а только после throw и вызовов функций (если они не помечены noexcept). Поэтому брошенное таким методом исключение может привести к новому segfault или std::terminate 🙂
Если в C++ процессе произошел SIGSEGV, то единственное что можно безопасно сделать — диагностику (стектрейс и т.п) и завершение процесса. Корректно восстановиться в общем случае нельзя.
using exceptions to catch segmentation faults?
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
It is implementation dependent; standard says nothing of it. If you’re
trying to find an equivalent to Java ‘s run-time exception by catching
Throwable, then you can try something like this, but it’s NOT
guaranteed be caught — thus you can still suffer from segmentation
fault or bus error in form of unexpected program abort.
try
<
//access invalid memory location.
>catch(. )
<
std::cerr John Carson
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
If you use vectors instead of arrays and use the at() member function rather
than the subscript operator, an exception is thrown for out of range
accesses. There is, however, no general C++ exception mechanism for
segmentation faults.
Windows has «structured exceptions» in addition to C++ exceptions. These
structured exceptions do include segmentation faults (or «access violations»
as they are more commonly called). Other platforms may have similar
facilities, but I don’t know about them.
—
John Carson
I posted some code that does that (for non-windows MT processes) in a
discussion in that subject sometime ago.
I hope you’ll find it use, and I’ll be glad to have feedback on it,
look at:
«Digital Puer» wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
If you use vectors instead of arrays and use the at() member function rather
than the subscript operator, an exception is thrown for out of range
accesses. There is, however, no general C++ exception mechanism for
segmentation faults.
Thank you for the info about vector::at. I looked through the docs
on vector, but there doesn’t seem to be an analogous ‘setter’
function for vector that can throw an exception. Is that right?
All I can find are append functions (e.g. push_back). I would
like ‘data[12] = foo’ to throw an exception if it’s past the end.
«Digital Puer» wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
If you use vectors instead of arrays and use the at() member
function rather than the subscript operator, an exception is thrown
for out of range accesses. There is, however, no general C++
exception mechanism for segmentation faults.
Thank you for the info about vector::at. I looked through the docs
on vector, but there doesn’t seem to be an analogous ‘setter’
function for vector that can throw an exception. Is that right?
All I can find are append functions (e.g. push_back). I would
like ‘data[12] = foo’ to throw an exception if it’s past the end.
at is overloaded to be both a getter and a setter function (just like the
subscript operator is). Thus you can use
Note that range errors are relative to the value returned by size(), not the
value returned by capacity(), e.g.,
vector vec;
vec.reserve(1);
try
<
vec.at(0) = 2;
>
catch (exception &e)
<
cout = size().
However
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
such mechanisms are platform specific and there is some good reason why
they have not been incooperated into the c++ language itself, for
example:
— common out-of-bounds errors often do not trigger a segfault because
your program has to access non-mapped or foreign memory for that to
happen. small off-bounds errors may pass unnoticed.
— writing into memory off bounds that your process owns will invoke
undefined behaviour and may wreak havoc.
— your process might have been corrupted on OS side before the
segmentation fault occured anyways.
in c++ you should always ensure that memory operations are valid and
use related tools like checked array index access, smart pointers and
the like if you need language support to do so.
if you are still interested into handling segfaults have a look into
platform specific newsgroups for more details.
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
It useless. After a segmentation fault, at least on unix, the behavior
of the process is undefined. You can not reliably handle or recover
from it. I see no reason why this wouldn’t apply for windoze.
http://www.opengroup.org/onlinepubs/. chap02_04.html
.
The behavior of a process is undefined after it ignores a SIGFPE,
SIGILL, SIGSEGV, or SIGBUS signal that was not generated by kill(),
sigqueue(), or raise().
.
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
It useless. After a segmentation fault, at least on unix, the behavior
of the process is undefined. You can not reliably handle or recover
from it. I see no reason why this wouldn’t apply for windoze.
It doesn’t apply. Of course a segmentation fault normally indicates a
program bug, so it is doubtful if the program can continue successfully from
that point on. However, it is certainly not the case that the behaviour of
the process becomes undefined as a matter of course.
For example, the following crashes on Windows:
int main()
<
int *ptr = 0;
*ptr = 2;
However, using structure exception handling, we can do this:
int main()
<
int *ptr = 0;
__try
<
*ptr = 2;
>
__except(EXCEPTION_EXECUTE_HANDLER)
<
cout Markus.Elfring
segmentation faults (e.g. when I access a location off
the end of an array)?
You get this error if any instruction in the code «attempts to access a
memory location in a way it is not allowed to». How much do you trust
your environment if it was tried to read or overwrite the value at an
unexpected address?
Is the infrastructure and mechanism for exception handling still
working after this kind of programming error was detected?
Should a direct program abort be the prefered reaction in this case so
that the error context can be analysed from a core dump file by a
debugger?
http://lambdacs.com/debugger/USENIX/. ENIX_2003.html
(Omniscient Debugging)
http://en.wikipedia.org/wiki/Buffer_overflow
How much effort do you put on a code structure with guarantees that out
of range accesses can not happen?
segmentation faults (e.g. when I access a location off
the end of an array)?
You get this error if an instruction in the code «attempts to access a
memory location in a way it is not allowed to». How much do you trust
your environment if it was tried to read or overwrite the value at an
unexpected address?
Is the infrastructure and mechanism for exception handling still
working after this kind of programming error was detected?
Should a direct program abort be the prefered reaction in this case so
that the error context can be analysed from a core dump file by a
debugger?
http://lambdacs.com/debugger/USENIX/. ENIX_2003.html
(Omniscient Debugging)
Can your program safely continue its execution if an
«access_violation_exception» will be caught?
Can any further damage from unexpected or undefined behaviour be
restricted?
How much effort do you put on a code structure with guarantees that out
of range accesses can not happen?
— http://en.wikipedia.org/wiki/Static_code_analysis
— http://en.wikipedia.org/wiki/Buffer_overflow
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
I have no clue what you mean by your allusion to Java. Segementation
faults are a foreign concept to Java as well. There’s no portable
way of catching them in C++ (and in many implementations there’s no
good way to catch them at all). There’s no indication that accessing
off the end of an array generates a segmentation fault either. Chances
are you just access/clobber some other piece of memory.
In Java, accessing an array beyond its allocated length generates
an exception. Since on my system (linux w/g++) accessing an
array beyond its allocation generally results in a seg fault, I am
trying to catch it with an exception handler to tell me where
the fault occurred.
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
It useless. After a segmentation fault, at least on unix, the behavior
of the process is undefined. You can not reliably handle or recover
from it. I see no reason why this wouldn’t apply for windoze.
http://www.opengroup.org/onlinepubs/. chap02_04.html
.
The behavior of a process is undefined after it ignores a SIGFPE,
SIGILL, SIGSEGV, or SIGBUS signal that was not generated by kill(),
sigqueue(), or raise().
.
I’m not trying to recover from the seg fault. I just want to find out
where in the code it happened.
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults
No
I’m not trying to recover from the seg fault. I just want to find out
where in the code it happened.
Even if it were possible, it would still not tell you where in the code
the error happened. When you catch an exception, all you know
is that it occurred somewhere inside the corresponding try-block.
So unless you were planning to wrap EVERY statement in a
try..catch block, you’re out of luck.
It sounds like you are looking for a program that will tell you
when you access memory that you shouldn’t. This is normally
called «a debugger» and there are lots of those available (valgrind
is one that springs to mind).
> Hi, I’m coming over from Java to C++, so please bear with me.
> In C++, is there a way for me to use exceptions to catch
> segmentation faults (e.g. when I access a location off
> the end of an array)?
>
> Thanks.
>
I have no clue what you mean by your allusion to Java. Segementation
faults are a foreign concept to Java as well. There’s no portable
way of catching them in C++ (and in many implementations there’s no
good way to catch them at all). There’s no indication that accessing
off the end of an array generates a segmentation fault either. Chances
are you just access/clobber some other piece of memory.
In Java, accessing an array beyond its allocated length generates
an exception. Since on my system (linux w/g++) accessing an
array beyond its allocation generally results in a seg fault, I am
trying to catch it with an exception handler to tell me where
the fault occurred.
Enable core-files and examine them with a debugger.
To enable core-files enter «ulimit -c unlimited». When your program
segfaults it generates a file named core or core.$PID. Start gdb with 2
arguments: the first is your program and the second is the core-file. In
gdb enter «where» and you get a nice stacktrace. It will be even nicer if
you compile your program with -g (and don’t use -O or -O2 or something).
Richter’s book, Programming Applications for Microsoft Windows.
See also:
Article «A Crash Course on the Depths of Win32™ Structured Exception
Handling»
by Matt Pietrek
Microsoft Systems Journal (January 1997)
http://www.microsoft.com/msj/0197/ex. exception.aspx
an exception. Since on my system (linux w/g++) accessing an
array beyond its allocation generally results in a seg fault, I am
trying to catch it with an exception handler to tell me where
the fault occurred.
I guess that the compiler should be corrected. Would you like to create
a bug report?
http://gcc.gnu.org/bugzilla/
http://en.wikipedia.org/wiki/GCJ
Do you find it under the known errors altready?
Hi, I’m coming over from Java to C++, so please bear with me.
In C++, is there a way for me to use exceptions to catch
segmentation faults (e.g. when I access a location off
the end of an array)?
Thanks.
I have no clue what you mean by your allusion to Java. Segementation
faults are a foreign concept to Java as well. There’s no portable
way of catching them in C++ (and in many implementations there’s no
good way to catch them at all). There’s no indication that accessing
off the end of an array generates a segmentation fault either. Chances
are you just access/clobber some other piece of memory.
In Java, accessing an array beyond its allocated length generates
an exception.
But not a segmentation fault.
Since on my system (linux w/g++) accessing an
array beyond its allocation generally results in a seg fault,
Sorry, but that’s not true. What causes a segmentation fault is
accessing a piece of memory that’s restricted (either not mapped,
or mapped for read only and you are trying to write it). Since
memory is allocated in chunks, and array allocations are interleaved
with other memory objects, the chances are unless you have a totally
wild subscript (much larger than the end), you won’t get a segmentation
fault directly from the access.
As others pointed out C (and hence by inheritance C++) does no range
checking on it’s arrays. You can use a different object in C++
(such as vector) to provide that. There are also packages out there
that instrument C++ in certain ways to do the check (at a substantial
performance penalty) to do these checks.
Your initial premise is wrong (that an array index error necessarily
generates a segmentation fault in C++) and there is no way to detect
either one.