Friday, April 8, 2022

[SOLVED] `DllNotFoundException: libc` when trying to run a mono app inside a snap package

Issue

When trying to bundle a mono app in a snap package, I'm getting this exception when the app tries to make a simple HTTP request:

System.AggregateException: One or more errors occurred. ---> System.DllNotFoundException: libc
  at (wrapper managed-to-native) System.Platform:uname (intptr)
  at System.Platform.CheckOS () [0x00022] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Platform.get_IsMacOS () [0x0000a] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetSystemWebProxy () [0x00149] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetDefaultWebProxy () [0x00016] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.get_DefaultWebProxy () [0x00024] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.GlobalProxySelection.get_Select () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.HttpWebRequest..ctor (System.Uri uri) [0x0008d] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest:.ctor (System.Uri)
  at System.Net.Http.HttpClientHandler.CreateWebRequest (System.Net.Http.HttpRequestMessage request) [0x00006] in <41c316444c8a4380b9344ba09eeb18de>:0 
  at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x0006a] in <41c316444c8a4380b9344ba09eeb18de>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000f3] in <41c316444c8a4380b9344ba09eeb18de>:0 
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.DllNotFoundException: libc
  at (wrapper managed-to-native) System.Platform:uname (intptr)
  at System.Platform.CheckOS () [0x00022] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Platform.get_IsMacOS () [0x0000a] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetSystemWebProxy () [0x00149] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetDefaultWebProxy () [0x00016] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.get_DefaultWebProxy () [0x00024] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.GlobalProxySelection.get_Select () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.HttpWebRequest..ctor (System.Uri uri) [0x0008d] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest:.ctor (System.Uri)
  at System.Net.Http.HttpClientHandler.CreateWebRequest (System.Net.Http.HttpRequestMessage request) [0x00006] in <41c316444c8a4380b9344ba09eeb18de>:0 
  at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x0006a] in <41c316444c8a4380b9344ba09eeb18de>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000f3] in <41c316444c8a4380b9344ba09eeb18de>:0 <---

System.AggregateException: One or more errors occurred. ---> System.DllNotFoundException: libc
  at (wrapper managed-to-native) System.Platform:uname (intptr)
  at System.Platform.CheckOS () [0x00022] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Platform.get_IsMacOS () [0x0000a] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetSystemWebProxy () [0x00149] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetDefaultWebProxy () [0x00016] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.get_DefaultWebProxy () [0x00024] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.GlobalProxySelection.get_Select () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.HttpWebRequest..ctor (System.Uri uri) [0x0008d] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest:.ctor (System.Uri)
  at System.Net.Http.HttpClientHandler.CreateWebRequest (System.Net.Http.HttpRequestMessage request) [0x00006] in <41c316444c8a4380b9344ba09eeb18de>:0 
  at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x0006a] in <41c316444c8a4380b9344ba09eeb18de>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000f3] in <41c316444c8a4380b9344ba09eeb18de>:0 
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.DllNotFoundException: libc
  at (wrapper managed-to-native) System.Platform:uname (intptr)
  at System.Platform.CheckOS () [0x00022] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Platform.get_IsMacOS () [0x0000a] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetSystemWebProxy () [0x00149] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.GetDefaultWebProxy () [0x00016] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.WebRequest.get_DefaultWebProxy () [0x00024] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.GlobalProxySelection.get_Select () [0x00000] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at System.Net.HttpWebRequest..ctor (System.Uri uri) [0x0008d] in <bd46d4d4f7964dfa9beea098499ab597>:0 
  at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest:.ctor (System.Uri)
  at System.Net.Http.HttpClientHandler.CreateWebRequest (System.Net.Http.HttpRequestMessage request) [0x00006] in <41c316444c8a4380b9344ba09eeb18de>:0 
  at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x0006a] in <41c316444c8a4380b9344ba09eeb18de>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000f3] in <41c316444c8a4380b9344ba09eeb18de>:0 <---

The snapcraft.yaml looks like this:

name: foo
base: core18 # the base snap is the execution environment for this snap
version: '0.3.1.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: bar
description: |
  baz

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: strict

apps:
  foo:
    command: bin/foo

parts:
  foo:
    plugin: dump
    source: ./staging
    stage-packages:
      - mono-complete

I create the snap this way:

./configure.sh --prefix=./staging
make
make install

snapcraft

I tried to fix this by bundling libc-related packages into the snap, adding them to stage-packages:

stage-packages:
  - mono-complete
  - libc6
  - libc6-dev
  - libc-dev-bin
  - libc-bin

But the problem still exists. And if I try to map these with layouts:

layout:
  /lib/x86_64-linux-gnu:
    bind: $SNAP/lib/x86_64-linux-gnu
  /usr/lib:
    bind: $SNAP/usr/lib

Then I get a crash:

$ snap run foo
execv failed: No such file or directory

Maybe that /usr/lib mapping was too much, but if I constrain it to this:

layout:
  /lib/x86_64-linux-gnu:
    bind: $SNAP/lib/x86_64-linux-gnu
  /usr/lib/x86_64-linux-gnu:
    bind: $SNAP/usr/lib/x86_64-linux-gnu

Then I still get the DllNotFoundException.


Solution

I finally solved this with this commit:

https://github.com/nblockchain/geewallet/commit/cba6abf52eaf2709b8b6a974079ac5713fd3aeec

The most important bit is to place this in the launcher script of your app:

if [[ $SNAP ]]; then
    PKG_DIR=$SNAP/usr


Answered By - knocte
Answer Checked By - Candace Johnson (WPSolving Volunteer)