2017-03-27 42 views
0

首先是一些背景,這個問題跟從System.DllNotFoundException: Unable to load DLL with dotnet coreDotnetcore和回調段錯誤

我們設法完全實現了一個在Windows中工作的互操作門面。然而,我們一直在linux中運行問題。我們隨機獲取細分故障。它有時會工作幾分鐘或幾小時,但最終會死亡。 以下是一些代碼片段。
N.B OnNotificationFromUnmanaged做的不僅僅是日誌,但是我們發現,無論它包含甚至無效,它仍然是應用程序死亡的關鍵點。

C#

private void OnNotificationFromUnmanaged(ZWNotification notification) 
{ 
    Console.WriteLine ("OnNotificationFromUnmanaged"); 
} 

var callback = Marshal.GetFunctionPointerForDelegate((ManagedNotificationsHandler)OnNotificationFromUnmanaged); 
Console.WriteLine($"Callback Ptr = {callback}"); 

Interop.RegisterCallback(callback); 
GC.Collect();//all calls should now segfault should the callback get GC'd 

CPP

#ifdef __GNUC__ 
#define EXPORT extern "C" 
#define CC 
#else 
#define EXPORT extern "C" __declspec (dllexport) 
#define CC __stdcall 
#endif 



typedef void(CC *CallBackDelegate)(ZWNotification); 

CallBackDelegate cb; //set by another function 


void OnNotification (Notification const* _notification, void* _context) 
{ 

     ZWNotification zw; 
     ...init stuff here 

     Log::Write(LogLevel_Info, "Callback to C#, %p", cb); 

     if (cb) 
       cb (zw); 
     Log::Write(LogLevel_Info, "Callback to C# - done"); 

} 

如果失敗,我們得到:

2017年3月27日15:53:22.005信息,回調到C#,0x7fe2184175fc $

dmesg reveals 

[7383.514872] DOTNET [21218]:段錯誤的7fe218418000 IP 00007fe218418000 SP 00007fe0ebffec88錯誤14

我們注意到,故障總是發生在1K範圍內的非託管結束後我們不確定這是否意義重大。 例如:

>  segfault at 7f72c17f4000 ip 00007f72c17f4000 sp 00007f718d0fac88 error 14 
>  segfault at 7f1656b75000 ip 00007f1656b75000 sp 00007f152d50bc88 error 14 

任何想法都非常歡迎!在這一點上,我們有點失去了生活的意願。

uname -a
Linux的DH-VM-ubuntu01 4.8.0-41泛型#44〜16.04.1-Ubuntu的SMP 星期五03月03日17點11分十六秒UTC 2017 x86_64的x86_64的x86_64的GNU/Linux的

dotnet --version
2.0.0 preview1-005416

+1

由於你的OnNotificationFromUnmanaged不是靜態的 - 也許它是垃圾收集的實例? – Evk

+0

它是一個類的私有函數。這個班是一個單身人士。你可以發佈一個例子作爲答案,也許我錯過了一些東西? – Mark

+1

只是一個想法。如果它是一個單例,它的實例存儲在靜態字段中,因此無法收集。 – Evk

回答

0

按@ EVK的評論我略微改變代碼

 private ManagedNotificationsHandler Handler; 

.....

Handler += OnNotificationFromUnmanaged; 

var callback = Marshal.GetFunctionPointerForDelegate(Handler); 
Interop.RegisterCallback(callback); 

而且似乎已經固定它。