Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-03

catch segfaults

11 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Xiangrong Fang
to Ewald

The document said it is "deprecated"? Also, I want this to be cross platform, not for unix only. The use case is:

try
  buf := GetMemory(1024);
  size := 10240;
  stream.Read(buf^, size);
except
  ??
end;

2013/3/14 Ewald

Show quoted text 12 lines
Once upon a time, Xiangrong Fang said: > Is it possible to use try...except to catch SIGSEGV? I don't know if it is possible, but how about using fpSignal()? See http://www.freepascal.org/docs-html/rtl/baseunix/fpsignal.html -- Ewald _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Tomas Hajny
to Xiangrong Fang
Xiangrong Fang wrote 8 lines
2013/3/14 Ewald > Once upon a time, Xiangrong Fang said: > > Is it possible to use try...except to catch SIGSEGV? > I don't know if it is possible, but how about using fpSignal()? See > http://www.freepascal.org/docs-html/rtl/baseunix/fpsignal.html > The document said it is "deprecated"? Also, I want this to be cross platform, not for unix only. The use case is:

The documentation proposes the alternative too (however that is still platform specific indeed).

Show quoted text 7 lines
try buf := GetMemory(1024); size := 10240; stream.Read(buf^, size); except ?? end;

What about trying it yourself?

{$MODE OBJFPC}
var
 P: PChar;
begin
 try
  WriteLn (P^);
 except
  WriteLn (0);
 end;
end.

D:\TEMP>ppc386 -Mobjfpc t.pas
Free Pascal Compiler version 2.6.2 [2013/02/12] for i386 Copyright (c) 1993-2012 by Florian Klaempfl and others Target OS: Win32 for i386
Compiling t.pas
t.pas(5,12) Warning: Variable "P" does not seem to be initialized Linking t.exe
9 lines compiled, 0.5 sec , 26704 bytes code, 1644 bytes data 1 warning(s) issued

D:\TEMP>t.exe
0

Tomas

Xiangrong Fang
to Mattias Gaertner

I am sorry that was what I thought, but does not work, see screenshot attached.

My environment:

~ $ uname -a
Linux fxrlm 3.5.0-21-generic #32-Ubuntu SMP Tue Dec 11 18:51:59 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
~ $ cat /etc/lsb-release
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=14
DISTRIB_CODENAME=nadia
DISTRIB_DESCRIPTION="Linux Mint 14 Nadia"
~ $

2013/3/14 Mattias Gaertner

Show quoted text 13 lines
On Thu, 14 Mar 2013 07:05:21 +0800 Xiangrong Fang wrote: > Is it possible to use try...except to catch SIGSEGV? yes. The exception class is EAccessViolation. Mattias _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jonas Maebe
to Xiangrong Fang: The document said it is "deprecated"? Also, I want this to be cross platform, not for…
Xiangrong Fang wrote 10 lines
The document said it is "deprecated"? Also, I want this to be cross platform, not for unix only. The use case is: try buf := GetMemory(1024); size := 10240; stream.Read(buf^, size); except ?? end;

That use case is a textbook example of why you should never try to catch and handle access violations, except possibly if you then warn the user that anything could happen if he continues (including erasing all files on his hard drive, if he's very unlucky).

An access violation often indicates that memory has been corrupted. Catching the access violation does not undo the memory corruption, it just informs you about this fact. If you continue after catching the exception in the above program, you will be working with corrupted memory, which means that the behaviour of your program becomes completely unpredictable afterwards.

Jonas

Tomas Hajny
to Xiangrong Fang: I am sorry that was what I thought, but does not work, see screenshot attached. My…
Xiangrong Fang wrote 10 lines
2013/3/14 Mattias Gaertner > On Thu, 14 Mar 2013 07:05:21 +0800 > Xiangrong Fang wrote: > > > Is it possible to use try...except to catch SIGSEGV? > > yes. The exception class is EAccessViolation. I am sorry that was what I thought, but does not work, see screenshot attached.

The screenshot does not show where exactly the problem happens (except for the address, but that is useless without context), i.e. if it is covered by the try..except construct. Try with the simple test I posted to see if it works or not.

In any case, Jonas is obviously right that you shouldn't try to catch SIGSEGV in such complex code (trying to catch the signal potentially happening in the middle of some nested processing which might leave the environment in completely undefined state).

Tomas

Jonas Maebe
to Tomas Hajny
Tomas Hajny wrote 10 lines
On Thu, March 14, 2013 09:23, Xiangrong Fang wrote: > > I am sorry that was what I thought, but does not work, see screenshot > attached. The screenshot does not show where exactly the problem happens (except for the address, but that is useless without context), i.e. if it is covered by the try..except construct.

Indeed, it probably crashes in FreeMemory or fs.free because the heap manager structures have been corrupted. The fs.Read itself does not necessarily raise an exception by itself in case there's still enough room in the heap block that contains buf, or if another one comes right after it.

Jonas

Martin
to Jonas Maebe: That use case is a textbook example of why you should never try to catch and handle…
Jonas Maebe wrote 26 lines
On 14 Mar 2013, at 01:48, Xiangrong Fang wrote: > The document said it is "deprecated"? Also, I want this to be cross > platform, not for unix only. The use case is: > > try > buf := GetMemory(1024); > size := 10240; > stream.Read(buf^, size); > except > ?? > end; That use case is a textbook example of why you should never try to catch and handle access violations, except possibly if you then warn the user that anything could happen if he continues (including erasing all files on his hard drive, if he's very unlucky). An access violation often indicates that memory has been corrupted. Catching the access violation does not undo the memory corruption, it just informs you about this fact. If you continue after catching the exception in the above program, you will be working with corrupted memory, which means that the behaviour of your program becomes completely unpredictable afterwards.

@Xiangrong

In fact (after I saw the screenshot, that indeed the alloc mem is less than the read), there is a possibility that the above good does NOT even crash. Yet it corrupts memory and the app will crash at a random later point.

If the 1024 bytes happen to be allocated in such way that they are followed by other already alocated memory, then they can be accessed without SigSegV.

Xiangrong Fang
to Martin

Thanks for the explanation. Now I see why my program some time crashed at gtk2*.inc...

2013/3/14 Martin

Show quoted text 44 lines
On 14/03/2013 09:47, Jonas Maebe wrote: On 14 Mar 2013, at 01:48, Xiangrong Fang wrote: The document said it is "deprecated"? Also, I want this to be cross platform, not for unix only. The use case is: try buf := GetMemory(1024); size := 10240; stream.Read(buf^, size); except ?? end; That use case is a textbook example of why you should never try to catch and handle access violations, except possibly if you then warn the user that anything could happen if he continues (including erasing all files on his hard drive, if he's very unlucky). An access violation often indicates that memory has been corrupted. Catching the access violation does not undo the memory corruption, it just informs you about this fact. If you continue after catching the exception in the above program, you will be working with corrupted memory, which means that the behaviour of your program becomes completely unpredictable afterwards. @Xiangrong In fact (after I saw the screenshot, that indeed the alloc mem is less than the read), there is a possibility that the above good does NOT even crash. Yet it corrupts memory and the app will crash at a random later point. If the 1024 bytes happen to be allocated in such way that they are followed by other already alocated memory, then they can be accessed without SigSegV. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal