Delphi App Communicates with a program that crashes Sometimes - the seller blames my Delphi application

I wrote a Delphi DLL that interacts with a third-party program through COM. Some users report that a third-party program sometimes works. Others using the same software have never crashed. When this failure occurs, the third-party program simply becomes unavailable in my application DLL.

The seller swears that this is a problem with the way Delphi DLLs are encoded, although they did not see the source code and cannot say what the DLL does to cause a crash, but they know that it is "something."

Besides the fact that I believe that a third-party program should not crash due to some minor problem in my DLL, let's say that there is something in my DLL that needs to be fixed.

How can I determine how this might affect my application? Does anyone have experience communicating through COM with a hypersensitive program like this? Are there any common things to look for that could cause a third-party program to crash?

+4
source share
6 answers
  • Make the customer happy.
  • Do not think that this is not your dll. Even if "Others using the software in the same way have never crashed," it may be that he does different things with different data ...
  • I suggest you set up logging in a text file in the "special" diagnostic version.
  • Write down everything, your options, your exceptions, and the steps you go through. Perhaps even the beginning and end of each function, and each other line.

Here's how he might look ...

Loaded DLL Started MyFunction1 with parameters: 1,4,hello 1 2 ... 500 Ended MyFunction1 

to do this, I would install several functions (in my own block):

 // opens a text file (fixed name), and appends to it. function InitializeLog; // closes the file function CloseLog; //add a log line. function Log(message:string='', startNewFunction:boolean:False); 

you would call it like this:

 function MyFunction1(Integer,Integer,String); begin try Log('Loaded DLL'); //use inttostr and do some string concats to get the params Log('Started MyFunction1 with parameters: 1,4,hello',true); //Then every other line: Log; //this would increment a global variable FuncLine:Integer //and write it to the file. except On E:Exception (Log('***'+E.Message)); end; end; 

Something like this should have {$ DEFINE} to enable these logging features in order to enable / disable diagnostic logging.

It may also be helpful.

+4
source

Look at Quality Central for report 58409.

This is about the mask of FPU and Dll.

Shortly speaking:

FPU mask settings determine how floating point exceptions are handled.

If you have, for example, Applicaion_A (encoded by some other) that loads Dll_A (also encoded by some other) and Dll_B (encoded by you), and your Dll changes the FPU mask, then this change is valid for Application_A and Dll_A as well .

Take an example: You installed, for example, WinZIP, SubVersion, etc., which register additional functions in the Windows file browser (pop-up menu with a right-click), and now you call TOpenDialog from your .exe application, then these additional functions may violate your FPU settings.

Hope this helps. (Extra tip: take Sysinternal to find out which DLLs are loaded by your application)

+4
source

Do you find using MadExcept ? If you catch an error in the interface methods, you can either register a call stack or show a dialog to the user and return the standard EOleSysError back to the calling exe.

Something like that:

  except on e: Exception do begin MadExcept.HandleException(); raise EOleSysError.Create('InitializeObject Failed', ErrorNumberToHResult(1 + CODE_BASE), 1); end; 

If the application freezes, but does not throw and throws, you can see what happens with the MadExcept madTraceProcess utility. This will allow you to create a call stack for the running application. Your dll will not be in the main thread, but you can see your call stack. This is a good way to tell if your dll really does something when a hang occurs.

I have a COM dll that interacts with an exe that does not use MadExcept, and this approach worked for me.

+3
source

If their program crashes when you use your published interface, I'm sure something is wrong with it. Proof is a completely different matter.

Is it possible to repeat the problem with a small Delphi application that you can provide to the provider? Monitoring reproducible failure can help convince them of the need for correction. At the very least, it can help determine what they think you are doing “wrong,” and tell how to do it “right.”

You can also try to duplicate the failure using C # or even VBScript.

+2
source

If I understand the situation correctly, fortunately, there are not so many on your side if your DLL does not crash, and the called third-party program simply ceases to be responsive. There is an error in the code, but it is caused only by calling your DLL. The debug log must really be executed in the application.
However, you can record all the calls that your DLL makes to this third-party program with parameters and some contextual information.
Then, looking at the last trace before the crash, you can get some information ...

+2
source

I don't know how madExcept etc. works, but I often use jclDebug.pas + JclHookExcept.pas (from the JEDI JCL library). This makes the Windows API hook, so it catches all (!) Exceptions, even if you do something like this:

 try raise exception.create('test'); except //eat exception end; 

Usually you do not see this exception because it is "eaten" ... But with the hook you get all the exceptions. For example: I once had a "catastrophic failure" in Midas.dll, and through the hook I saw the error "lost database connection" in the dll before this exception, so I knew what happened. (btw: JclHookExcept.pas = hook, jclDebug.pas = strack trace).

Now I see that JclHookExcept.pas also has a "JclHookExceptionsInModule" procedure, so you can force (?) To catch all exceptions from a specific library ...

Some demo codes:

 procedure AnyExceptionNotify(ExceptObj: TObject; ExceptAddr: Pointer; OSException: Boolean); begin //log exception end; initialization // Start Exception tracking JclStartExceptionTracking; JclTrackExceptionsFromLibraries; JclStackTrackingOptions := [stStack, stRawMode, stAllModules]; // Assign notification procedure for hooked RaiseException API call. This // allows being notified of any exception JclAddExceptNotifier(AnyExceptionNotify); 
+2
source

Source: https://habr.com/ru/post/1286758/


All Articles