Recent

Author Topic: CryptLib + SigSev (Runtime error 216) on program exit  (Read 466 times)

KennethH

  • New member
  • *
  • Posts: 6
CryptLib + SigSev (Runtime error 216) on program exit
« on: January 30, 2023, 06:00:05 pm »
Hi all...

Let me preface this with "I have an acceptable work-around"...

I am linking to CryptLib in a rather complex program that is throwing a mysterious run-time error on exit. After much stripping down, here is the MOST simple code that will throw the error:

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. function cryptInit: Integer; stdcall; external 'CL64.DLL';
  4. function cryptEnd: Integer; stdcall; external 'CL64.DLL';
  5.  
  6. begin
  7.  
  8.   if cryptInit = 0 then
  9.     Writeln('Init!');
  10.  
  11.   cryptEnd;
  12.   Writeln('Complete');
  13.  
  14. end.
  15.  

This code runs fine in Windows 10 but throws the error on Windows 2012 Server R2.

Notes:
  • Compiled on FPC 3.04 and on FPC 3.2.2, as I read on this forum 3.0.4 has a bug that can cause this
  • Error only on that one OS. SAME code and SAME DLL work in Windows 10
  • Works fine in 2012 when compiled in 32-bit mode

Question to the forum: Am I missing any obvious compiler options that would help debug this? I've tried {$S+} and {$INLINE OFF}

Quote from: DebugLog
=library-loaded,id="C:\\Windows\\SYSTEM32\\cryptbase.dll",target-name="C:\\Windows\\SYSTEM32\\cryptbase.dll",host-name="C:\\Windows\\SYSTEM32\\cryptbase.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\bcryptprimitives.dll",target-name="C:\\Windows\\SYSTEM32\\bcryptprimitives.dll",host-name="C:\\Windows\\SYSTEM32\\bcryptprimitives.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\cryptsp.dll",target-name="C:\\Windows\\SYSTEM32\\cryptsp.dll",host-name="C:\\Windows\\SYSTEM32\\cryptsp.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\system32\\shell32.dll",target-name="C:\\Windows\\system32\\shell32.dll",host-name="C:\\Windows\\system32\\shell32.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\system32\\shlwapi.dll",target-name="C:\\Windows\\system32\\shlwapi.dll",host-name="C:\\Windows\\system32\\shlwapi.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\SHCore.dll",target-name="C:\\Windows\\SYSTEM32\\SHCore.dll",host-name="C:\\Windows\\SYSTEM32\\SHCore.dll",symbols-loaded="0",thread-group="i1"
=library-loaded,id="C:\\Windows\\SYSTEM32\\profapi.dll",target-name="C:\\Windows\\SYSTEM32\\profapi.dll",host-name="C:\\Windows\\SYSTEM32\\profapi.dll",symbols-loaded="0",thread-group="i1"
=thread-created,id="2",group-id="i1"
~"[New Thread 5380.0x27ac]\n"
*running,thread-id="all"
=thread-exited,id="2",group-id="i1"
*stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",frame={addr="0x0000000000000000",func="??",args=[]},thread-id="1",stopped-threads="all"
(gdb)
<info program>
&"info program\n"
~"\tUsing the running image of child Thread 5380.0x2718.\n"
~"Program stopped at 0x0.\n"
~"It stopped with signal SIGSEGV, Segmentation fault.\n"

===WORK AROUND===

The following code does NOT throw the error. Because there was no change in the DLL, it leads me to search for the problem in FPC-side, not the within the DLL

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. uses Windows;
  4.  
  5. type
  6.   CFunction = function: Integer; stdcall;
  7.  
  8. var
  9.   cryptInit, cryptEnd: CFunction;
  10.   H: THandle;
  11. begin
  12.  
  13.   H := LoadLibrary('CL64.DLL');
  14.   cryptInit := CFunction(GetProcAddress(H, 'cryptInit'));
  15.   cryptEnd := CFunction(GetProcAddress(H, 'cryptEnd'));
  16.  
  17.   if cryptInit() = 0 then
  18.     Writeln('Init!');
  19.  
  20.   cryptEnd();
  21.  
  22.   FreeLibrary(H);
  23.   Writeln('Complete');
  24.  
  25. end.
  26.  

I consider this an acceptable work-around but the programmer in me cannot let this go. Any help on compiler directives appreciated

KennethH

  • New member
  • *
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #1 on: January 30, 2023, 06:06:32 pm »
Note that I do not 100% rule out an error in the DLL.

For example, in cryptlib.pas that comes from their site, we see:

Code: Pascal  [Select][+][-]
  1. const
  2.   {$IFDEF WIN32}
  3.     cryptlibname = 'CL32.DLL';  { dynamic linkname for Windows (Delphi) }
  4.   {$ELSE}
  5.     cryptlibname = 'libcl.so';  { library name for Unix/Linux  (Kylix) }
  6.                  { symbolic link should be used for libcl.so -> libcl.so.3.x.y }
  7.   {$ENDIF}
  8.  
  9. function cryptInit: Integer;
  10. {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF} external cryptlibname;
  11.  
  12.  
  13. function cryptEnd: Integer;
  14. {$IFDEF WIN32} stdcall; {$ELSE} cdecl; {$ENDIF} external cryptlibname;
  15.  

which does not play nicely in WIN64. So I had to make some corrections to their lib just to get it to run in Win10. I'm poking at the code right now in Visual Studio to see if I can spot other problem spots.

jamie

  • Hero Member
  • *****
  • Posts: 5160
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #2 on: January 30, 2023, 06:11:36 pm »
Try appending the "name" at the end.
Fascal is not a case sensitive language. But u can specify the real name at the end.
......name 'theName'
U can even use index if u know it.
The only true wisdom is knowing you know nothing

KennethH

  • New member
  • *
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #3 on: January 30, 2023, 06:21:16 pm »
Try appending the "name" at the end.
Fascal is not a case sensitive language. But u can specify the real name at the end.
......name 'theName'
U can even use index if u know it.

Thank you, however still no-go

Code: Pascal  [Select][+][-]
  1. program Test;
  2.  
  3. function cryptInit: Integer; stdcall; external 'CL64.DLL' name 'cryptInit';
  4. function cryptEnd: Integer; stdcall; external 'CL64.DLL' name 'cryptEnd';
  5.  
  6. begin
  7.  
  8.   if cryptInit = 0 then
  9.     Writeln('Init!');
  10.  
  11.   cryptEnd;
  12.   Writeln('Complete');
  13.  
  14. end.  

Quote from: Output
Init!
Complete
Runtime error 216 at $0000000000000000
  $0000000000000000
  $00007FFDB166909A
  $00007FFDB16B381B
  $00007FFDD590C414
  $00007FFDD590B822
  $00007FFDD59084F8
  $00007FFDD5114F8A
  $0000000100007F0B
  $000000010000383F
  $000000010000162D
  $0000000100001646
  $0000000100007F70
  $00000001000015A0
  $00007FFDD5111412
  $00007FFDD5905504

jamie

  • Hero Member
  • *****
  • Posts: 5160
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #4 on: January 30, 2023, 06:24:19 pm »
Looks like u r in 64bit mode.?

R u sure that is a 32bit dll?

I meant 64 bit
« Last Edit: January 30, 2023, 06:25:56 pm by jamie »
The only true wisdom is knowing you know nothing

KennethH

  • New member
  • *
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #5 on: January 30, 2023, 06:37:35 pm »
Looks like u r in 64bit mode.?

R u sure that is a 32bit dll?

I meant 64 bit

Confirming 64-bit.
Same .exe and same .dll work fine in Win10

Thaddy

  • Hero Member
  • *****
  • Posts: 12887
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #6 on: January 30, 2023, 06:40:25 pm »
Well, the cryptinit fails, so you have to look for that....
Who is responsable for that!! The caller or the callee.. Out! ya'll, NOW. In UTC time, please, so maybe Yesterday or tomorrow.

KennethH

  • New member
  • *
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #7 on: January 30, 2023, 06:47:07 pm »
Well, the cryptinit fails, so you have to look for that....

That 0 is a success. From within the DLL code:

Code: C  [Select][+][-]
  1. #define CRYPT_OK                                0               /* No error */
  2.  

Also, for fun, I've nerfed the initialization code in the DLL

Code: C  [Select][+][-]
  1. C_RET cryptInit( void )
  2.         {
  3.                 return( CRYPT_OK );
  4.         }
  5.  
  6. C_RET cryptEnd( void )
  7.         {
  8.         return (CRYPT_OK);
  9.         }
  10.  

KennethH

  • New member
  • *
  • Posts: 6
Re: CryptLib + SigSev (Runtime error 216) on program exit
« Reply #8 on: January 31, 2023, 09:50:29 pm »
Ok, everyone. FPC is off the hook. Turns out the library was invoking code from Win2k16+ that my 2k12 box didn't have.

This was occurring in PROCESS_DETACH which will be notoriously difficult for a debugger to snag onto.

But it worked in 32-bit :o
...Well, it's a null pointer operation (in C, not even managed code). 32-bit may have had garbage in there pointing the read operation somewhere friendly. Whereas in 64, Windows came down with the ban-hammer and said you most certainly cannot read there.

 

TinyPortal © 2005-2018