?
Solved

Access Violation Exception

Posted on 2003-02-22
16
Medium Priority
?
1,575 Views
Last Modified: 2012-06-27
Delphi-Experts,

I have written a program to display JPG-pictures using Delphi 3. For displaying the pictures I use components I haven't written myself.

When reading some bad JPG-pictures (maybe 1 in a 100) I get an access violation:

access violation at 0x232835: read of address 0xfff4b134
83 3A 00 74 63 E8 39 10 00 00 64 8B

I'll include a piece of two sources:
1) TMultip.pas : calls the function 'jpgfile';
2) DLL95V1.pas : calls the function 'readjpgfile'.

Source: TMultip.pas

uses
{$IFDEF DEL32}
  Windows,
{$ELSE}
  WinTypes,
  WinProcs,
{$ENDIF}
  DLL95V1, SysUtils, Messages, Classes, Graphics,
  Forms, Controls, Extctrls, StdCtrls, Menus, Mask,
  Buttons, Printers, Setsr31, Setcr31;


type
  published
    property ImageName  : String read GetMultiBitmap write WriteMultiName;

function TPMultiImage.GetMultiBitmap :  String;
var    Bitmap     : TBitmap;
       Pextension : String[4];
       OnExcept   : Boolean;
       Dith       : Integer;
       ReadRes    : Integer;

begin


 if Pextension = '.JPG' then begin
    try
     FreeMsg;
     Bitmap := TBitmap.Create;
     if not jpgfile(FFilename, ReadRes, Dith, Bitmap, TPMultiImageCallBack) then
       ErrorMessage('Reading jpg file failed');
    except
     Picture.Graphic := nil;
     Bitmap.Free;
     OnExcept:=True;
    end;
     if OnExcept then Goto BreakIt;
     Picture.Graphic:=Bitmap;
     Bitmap.Free;
     GetInfoAndType(FFilename);
 end;


end;


Source: DLL95V1.pas

const
  ImageLibDLL = 'SKY32V3C.DLL';

{Interface call}
Function jpgfile(Filename          : String;
                 Resolution        : Integer;
                 Dither            : Integer;
            var  Bitmap            : TBitmap;
           CallBackFunction        : TCallBackFunction) : Boolean;

var
 Fn   : Array[0..255] of Char;
 HPAL : HPalette;
 hBMP : HBitmap;
 Res  : SmallInt;
begin
  hPal:=GlobalPalette;
  StrPCopy(Fn, Filename);
  Res:=readjpgfile(Fn,
                   SmallInt(Resolution),
                   1, {size, 1= 1/1}
                   SmallInt(Dither),
                   hBMP,
                   HPAL,
                   CallBackFunction,
                   ShowErrorInDll);

 Bitmap.Handle := hBMP;
 Bitmap.Palette := HPAL;

 If Res < 1 then begin
   DllErrorProc(Res);
   Result:=False
 end else
   Result:=True;
  {$IFDEF ILTRIAL}
   Validate;
  {$ENDIF}
end;

Function readjpgfile; external ImageLibDLL index INDEX_READJPGFILE;

My actual question is how can I catch the 'access violation' and give a decent message instead of the application closing down.

Regards,
Gandalf the Grey.
0
Comment
Question by:detempel
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
16 Comments
 
LVL 3

Expert Comment

by:sfock
ID: 7999812
can you tell us, where exactly the Exception occures?
I can only guess that. it might be easier if you'd tell use where it is raised.

until then i can't say much except of
  except
    Picture.Graphic := nil;
    Bitmap.Free;
    OnExcept:=True;
   end;
   if OnExcept then Goto BreakIt;
lokks like pretty bad style .. but anyhow i can't encoubter a mistake within ...
0
 

Author Comment

by:detempel
ID: 8000653
I have traced the exception to:

   if not jpgfile(FFilename, ReadRes, Dith, Bitmap, TPMultiImageCallBack) then
      ErrorMessage('Reading jpg file failed');

I have put messages before and after this statement. The message before the statement is shown and immediately after that I get the 'access violation'. So it seems the try .. except construct doesn't catch the access violation. I think it is in the function 'jpgfile' somewhere.

I'm not very experience with catching exceptions. Apparently the 'access violation' exception can't be catched by the try .. except construct?
0
 
LVL 3

Expert Comment

by:sfock
ID: 8002215
I am still not sure what is happening at the callbackfunction? Anyhow i guess that is not the problem.
But what is happing at the jumppoint "BreakIt"

I'd guess that any exception occures it is catched by the except block and something within this "BreakIt" makes the access violation ...

show me the BreakIt please
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:detempel
ID: 8002571
BreakIt is a declared as a label and that label is at the end of the function TPMultiImage.GetMultiBitmap (using labels and jumps is indeed bad practice).

 if Pextension = '.JPG' then begin
    try
     FreeMsg;
     Bitmap := TBitmap.Create;
     if not jpgfile(FFilename, ReadRes, Dith, Bitmap, TPMultiImageCallBack) then
       ErrorMessage('Reading jpg file failed');
    except
     Picture.Graphic := nil;
     Bitmap.Free;
     OnExcept:=True;
    end;
     if OnExcept then Goto BreakIt;
     Picture.Graphic:=Bitmap;
     Bitmap.Free;
     GetInfoAndType(FFilename);
 end;

 BreakIt:
 Temps:=UpperCase(FFilename);
 result:=Temps;
end;

Temps and FFilename are of type TFilename. FFilename is part of the type TPMultiImage.

I have put extra messages between the code but when I load the faulty jpg-picture I only get the access violation. I have put the first message at the beginning of the function TPMultiImage.GetMultiBitmap.

I have tried extra messages before with another faulty jpg-picture. In that case the last message that showed was the message before the check on 'jpgfile'. I'm sure I used the same procedure 'ErrorMessage' to display the debug-information.
0
 
LVL 3

Expert Comment

by:sfock
ID: 8002598
hmm it does not look like if the BreakIt code would be the problem ...
Are you debugging in the IDE?? if the option is set it does alway show any exception also if it was catched and not be shown to the user ...

but if this is not your problem then place a message here :
  except
    ShowMessage('onExceptIN');
    Picture.Graphic := nil;
    ShowMessage('onExcept1');
    Bitmap.Free;
    ShowMessage('onExcept2');
    OnExcept:=True;
    ShowMessage('onExceptOUT');
   end;
at least 'onExceptIN' should appear ...
0
 

Author Comment

by:detempel
ID: 8002799
I have altered the code this way:

    if not jpgfile(FFilename, ReadRes, Dith, Bitmap, TPMultiImageCallBack) then
       ErrorMessage('Reading jpg file failed');
    except
     { ErrorMessage('Aan het begin van het except-block'); }
     ShowMessage('onExceptIN');
     Picture.Graphic := nil;
     { ErrorMessage('Vrijgeven Graphic'); }
     ShowMessage('onExcept1');
     Bitmap.Free;
     { ErrorMessage('Vrijgeven Bitmap'); }
     ShowMessage('onExcept2');
     OnExcept:=True;
     { ErrorMessage('Aan het einde van het except-block') }
     ShowMessage('onExceptOUT')
    end;
     if OnExcept then Goto BreakIt;

Testing from within the IDE doesn't display the message 'onExceptIN'.

The code is part of a package. After I change the code I recompile the package. And then I recompile my program with the altered package (I'm not sure but I think that a showmessage in a package doesn't work).
0
 
LVL 3

Expert Comment

by:sfock
ID: 8003685
>showmessage in a package doesn't work
why shouldn't it?

anyhow let me carry the informations together:

An Access violation occures within the function jpgfile

the call of this function is withion a try except block

but the except block is nerver entered

is that correct?

This should not be possible. The only way i have ever seen a similar behavior is if an exception occures within a except or finally block.

i can't see such a mistake here. It might happen at readjpgfile() or the CallBackFunction.

maybe we should take a look in there ... except of that i have no other ideas just a desperate trial:

change the except block as follows:

  except
    on e : exception do begin
      // you can also use your ErrorMessage instead of showMessage
      showMessage('Ex:'+e.ClassName+' msg: '+e.message);
      Picture.Graphic := nil;
      Bitmap.Free;
      OnExcept:=True;
    end;
   end;
0
 

Author Comment

by:detempel
ID: 8004645
I have discovered with this JPG-picture the access violation apparently occurs at another place. I have traced it to this piece of code:

  StrPCopy(Fn, Filename);
  ShowMessage('Na StrPCopy');
  try
    Res:=fileinfo(Fn,
                  @Ft,
                  BFwidth,
                  BFHeight,
                  BFbitspixel,
                  BFplanes,
                  BFnumcolors,
                  @Fc,
                  ShowErrorInDll);
  except
    ShowMessage('Oops')
  end;

The try-part triggers the access violation but I get no message 'Oops'. I do get the message 'Na StrPCopy'.

The function 'fileinfo' is declared as follows:

Function fileinfo; external ImageLibDLL index INDEX_FILEINFO;
0
 
LVL 3

Accepted Solution

by:
sfock earned 600 total points
ID: 8007139
well, i am really sorry, i have no further idea.
There are severeal reasons why a AcVio could appear, when calling a DLL function, but anyhow it has to be catched by this except block!!!

if not i won't know a reason. The only thing i can imagine is that your debugging results are not correct ...
If you'd place another message behind the try...except block would it appear?

StrPCopy(Fn, Filename);
 ShowMessage('Na StrPCopy');
 try
   Res:=fileinfo(Fn,
                 @Ft,
                 BFwidth,
                 BFHeight,
                 BFbitspixel,
                 BFplanes,
                 BFnumcolors,
                 @Fc,
                 ShowErrorInDll);
 except
   ShowMessage('Oops')
 end;
 ShowMessage('FileInfo done')

0
 

Expert Comment

by:pderuiter
ID: 8007621
What's that "showErrorInDll"? the way an access violation will escape from your try except is if it is "handled" by another try except.
0
 
LVL 3

Expert Comment

by:sfock
ID: 8007668
pderuiter
but it would not appear then...
0
 

Author Comment

by:detempel
ID: 8010466
const
 ShowErrorInDll    = 0; {1 is show messagebox in dll 0 is in this unit}

I have tried changing ShowErrorInDll to 1 but that didn't change a thing. Since 'FileInfo' is a black box to me I don't know what else to do.

Here's the definition of the function call:

{DLL call}
Function   fileinfo(Filename       : PChar;
                    FileType       : PChar;
                var Fwidth         : SmallInt;
                var FHeight        : SmallInt;
                var Fbitspixel     : SmallInt;
                var Fplanes        : SmallInt;
                var Fnumcolors     : SmallInt;
                    Fcompression   : PChar;
                   ShowDllErrorMsg : SmallInt) : SmallInt; {$IFDEF DEL32}
                                                           StdCall;
                                                         {$ELSE}
                                                           Far;
                                                         {$ENDIF}

When I try to read the picture using 'IrfanView' I get the error 'Bogus Huffman table definition'.

Since ShowErrorInDll has the value zero I would expect the error to be catched by the try ... except construct.
0
 

Author Comment

by:detempel
ID: 8023435
I have taken another approach. I have tested using the JPEG-demo in the directory help/examples/jpeg:

procedure TForm1.OpenFile(const Filename: string);
begin
  try
    Image1.Picture.LoadFromFile(Filename);
  except
    on EInvalidGraphic do
      Image1.Picture.Graphic := nil;
    else ShowMessage('Oops')
  end;
  SetJPEGOptions(self);
end;

I get an error message 'Project JPEGPROJ.exe raised exception class EJPEG with message 'JPEG error #30'. Process stopped. Use Step or Run to continue.'. When I press Run the program continues without showing the message 'Oops'.

So in this case the except-block is also not entered and this is an example from Borland.
0
 

Expert Comment

by:joined
ID: 8563204
You can try EurekaLog (www.eurekalog.com).

EurekaLog is an add-in tool that gives to your application (GUI, Console, Web, etc.) the ability to catch every exception, and generates a detailed log of call stack (with unit, class, method and line #), showing and sending it back to you via email.

--
Best regards...

Fabio Dell'Aria.
0
 

Expert Comment

by:serg1233
ID: 8642467
May be THE PROBLEM in  "StrPCopy" - it doesnt work correctly if it have "0"...
it looking for "0" like the end of the string...:-)

All the Best
0
 

Author Comment

by:detempel
ID: 8645530
I have closed this question by awarding the points to the first one helping me out. I have found a work around where I can catch the error-message and thus prevent the 'access violation' from occuring.

Regards,
Gandalf the Grey.
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question