DLLImport failed in Mono (linux): icall_wrapper_mono_marshal_free

I am having a problem with Mono Interop on Linux. I have a native shared library (made in Lazarus) that I need to use in a C # build. The shared library is used by the Mono C # assembly on Windows and Linux.

The assembly loads the shared library through DllImport at run time and calls the exported function, which generates the file, and returns a string with the new file name. A function in the shared library works fine, but on Linux, Mono runtime drops with Object .__ icall_wrapper_mono_marshal_free when the function returns. This works fine using Mono on Windows.

I did some tests, and I can say that the shared library is working (a new file is generated at the specified path), but in the end there is a crash at runtime. It seems that the runtime has problems marshaling the resulting string back to the assembly, because it works if I use an exported function that returns an int.

My shared library looks something like this:

library fileProcessing;

{$mode objfpc}{$H+}
...

function ProcessFile(File, ResultPath: PChar): PChar; cdecl; // returns a null-terminated string, with a C ABI calling convention
var
  sFile, sPath, sResult: string;
begin
  sFile := StrPas(File);
  sPath := StrPas(ResultPath);
...
  sResult := GenerateNewFile(sFile, sPath); // helper function that generates the file and returns its filename
  Result := stralloc(length(sResult) + 1);
  Result := strpcopy(Result, sResult);
end;
...

exports ProcessFile name 'ProcessFile';

The calling C # assembly is as follows:

namespace SIG
{
  public class TsigKernel
  {
...
    [DllImport("fileProcessing.so", CharSet=CharSet.Ansi,
         EntryPoint="ProcessFile",
         CallingConvention=CallingConvention.Cdecl, SetLastError = true)]
    private static extern string ex_ProcessFile(string File, string ResultPath);

    // managed wrapper for the shared library exported function
    public string ProcessFile(string File, string ResultPath)
    {
     return ex_ProcessFile(File, ResultPath);
    }
...
  }
}

I tried several alternatives (returning my own line from the exported function, changing the calling convention to stdcall in the assembly and shared library, changing the encoding in DllImport).

I'm sure something is missing, but I did not find anything about this issue on Google.

My accident reads:

=================================================================  
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.  
=================================================================

Stacktrace:
  at (wrapper managed-to-native) object.__icall_wrapper_mono_marshal_free (intptr) <0x00004>
  at (wrapper managed-to-native) object.__icall_wrapper_mono_marshal_free (intptr) <0x00004>
  at (wrapper managed-to-native) SIG.TsigKernel.ex_ProcessFile (string, string) <0x00064>
  at SIG.TsigKernel.ProcessFile (string, string) <0x00010>
  at TEST.Form1.Form1_Load (object,System.EventArgs) <0x00047>
  at System.Windows.Forms.Form.OnLoad (System.EventArgs) <0x00060>
  at System.Windows.Forms.Form.OnLoadInternal (System.EventArgs) <0x00081>
  at System.Windows.Forms.Form.OnCreateControl () <0x00051>
  at System.Windows.Forms.Control.CreateControl () <0x0012e>
  at System.Windows.Forms.Control.WmShowWindow (System.Windows.Forms.Message&) <0x0010f>
  at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message&) <0x00292>
  at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message&) <0x00013>
  at System.Windows.Forms.ContainerControl.WndProc (System.Windows.Forms.Message&) <0x00051>
  at System.Windows.Forms.Form.WndProc (System.Windows.Forms.Message&) <0x0022a>
  at System.Windows.Forms.Control/ControlWindowTarget.OnMessage (System.Windows.Forms.Message&) <0x0001d>
  at System.Windows.Forms.Control/ControlNativeWindow.WndProc (System.Windows.Forms.Message&) <0x0002d>
  at System.Windows.Forms.NativeWindow.WndProc (intptr,System.Windows.Forms.Msg,intptr,intptr) <0x001eb>
  at System.Windows.Forms.XplatUIX11.SendMessage (intptr,System.Windows.Forms.Msg,intptr,intptr) <0x002ae>
  at System.Windows.Forms.XplatUIX11.MapWindow (System.Windows.Forms.Hwnd,System.Windows.Forms.WindowType) <0x0019a>
  at System.Windows.Forms.XplatUIX11.CreateWindow (System.Windows.Forms.CreateParams) <0x00bb4>
  at System.Windows.Forms.XplatUI.CreateWindow (System.Windows.Forms.CreateParams) <0x0001d>
  at System.Windows.Forms.NativeWindow.CreateHandle (System.Windows.Forms.CreateParams) <0x00030>
  at System.Windows.Forms.Control.CreateHandle () <0x0007f>
  at System.Windows.Forms.Form.CreateHandle () <0x00014>
  at System.Windows.Forms.Control.CreateControl () <0x0008a>
  at System.Windows.Forms.Control.SetVisibleCore (bool) <0x00079>
  at System.Windows.Forms.Form.SetVisibleCore (bool) <0x0021d>
  at System.Windows.Forms.Control.set_Visible (bool) <0x0002c>
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Control.set_Visible (bool) <0x00057>
  at System.Windows.Forms.Application.RunLoop (bool,System.Windows.Forms.ApplicationContext) <0x001f9>
  at System.Windows.Forms.Application.Run (System.Windows.Forms.ApplicationContext) <0x00052>
  at System.Windows.Forms.Application.Run (System.Windows.Forms.Form) <0x00033>
  at TEST.Program.Main () <0x00044>
  at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0x0003a>

Native stacktrace:
mono [0x80d36a9]
[0xffffe410]
[0xffffe430]
/lib/libc.so.6(gsignal+0x4f) [0xb76430cf]
/lib/libc.so.6(abort+0x187) [0xb76449e7]
/lib/libc.so.6 [0xb767f4ed]
/lib/libc.so.6 [0xb768550b]
/lib/libc.so.6 [0xb7686de4]
/lib/libc.so.6(cfree+0x6d) [0xb7689fdd]
/usr/lib/libglib-2.0.so.0(g_free+0x36) [0xb780d886]
[0xb6561634]
[0xb5786a5d]
[0xb57869d1]
[0xb57866c8]
[0xb5786599]
[0xb578632a]
[0xb5785f7a]
[0xb605dbe7]
[0xb578c7c0]
[0xb578bbfb]
[0xb57820c4]
[0xb578208a]
[0xb5781eeb]
[0xb578b95e]
[0xb578b936]
[0xb578ac74]
[0xb5788acf]
[0xb578c4b3]
[0xb605eca5]
[0xb605e0e6]
[0xb605e069]
[0xb605ddf0]
[0xb57804bd]
[0xb605db43]
[0xb57938a2]
[0xb57800a6]
[0xb57937f5]
[0xb5793798]
[0xb577f062]
[0xb577ee13]
[0xb577eacc]
[0xb71ce1f5]
[0xb71ce26b]
mono [0x8063552]

Any ideas?

+3
3

, string native. , Mono Interop with Native Libraries (Strings), , . , StringBuilder - .

+2

, , # , , g_free Linux CoTaskMemFree Windows. g_alloc CoTaskMemAlloc , IntPtr # Marshal.PtrToStringAuto . , - .

namespace SIG
{
  public class TsigKernel
  {
    ...
    [DllImport("fileProcessing.so", CharSet=CharSet.Ansi,
         EntryPoint="ProcessFile",
         CallingConvention=CallingConvention.Cdecl, SetLastError = true)]
    private static extern IntPtr ex_ProcessFile(string File, string ResultPath);

    [DllImport("fileProcessing.so", CharSet=CharSet.Ansi,
         EntryPoint="FreeText",
         CallingConvertion=CallingConvention.Cdecl, SetLastError = true)]
    private static extern void ex_FreeText(IntPtr str);

    // managed wrapper for the shared library exported function
    public string ProcessFile(string File, string ResultPath)
    {
      IntPtr str_ptr = ex_ProcessFile(File, ResultPath);
      string res = Marshal.PtrToStringAnsi(str_ptr);
      ex_FreeText(str_ptr);
      return res;
    }
    ...
  }
}

FreeText:

function FreeText(Str: PChar); cdecl; // frees previously allocated string, with a C ABI calling convention
begin
  strdispose(Str);
end;
+2

The question is, what does stralloc use? In Mono, the equivalent code uses g_free for the returned blob, which maps to libc free. Most likely, StrAlloc is doing something else.

0
source

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


All Articles