diff mbox

Problems with uClicbc and libc.so.6

Message ID CA+TH9VnFAqd-4ZFQ3Bi2kcDD1rqX-de8BwvErpUxOhaytGF7EA@mail.gmail.com
State Not Applicable
Headers show

Commit Message

Angelo Compagnucci Oct. 9, 2014, 3:58 p.m. UTC
Hi Thomas,

Sorry for the reply, but just for the sake of completeness, I rebuilt
everithing from scratch after pulling latest changes from git.

I'm running buildroot 2014.11-git-00582-g9951845 with the patch you
can find attached. Attached you can find also my .config.

Thank you for your time!

Angelo


2014-10-09 15:07 GMT+02:00 Thomas Petazzoni
<thomas.petazzoni@free-electrons.com>:
> Dear Angelo Compagnucci,
>
> On Thu, 9 Oct 2014 14:58:55 +0200, Angelo Compagnucci wrote:
>
>> > If something depends on libc.so.6, it means it was built against glibc,
>> > and cannot work against uClibc. So either it's something built from
>> > source, and you should rebuilt it with the uClibc toolchain. Or it's
>> > something available as a pre-built binary for which you don't have the
>> > source, in which case you have no other choice than using glibc.
>>
>> I just rebuilt everything from scratch using the latest buildroot git
>> and the problem persists.
>> The package I'm using is more or less this one:
>>
>> http://patchwork.ozlabs.org/patch/392957/, I've only added a small
>> patch to make compile cleanly with uClibc.
>>
>> diff -purN mono-native-3.8.0.orig/libgc/include/gc.h
>> mono-native-3.8.0/libgc/include/gc.h
>> --- mono-native-3.8.0.orig/libgc/include/gc.h 2014-10-07
>> 15:00:21.259466731 +0200
>> +++ mono-native-3.8.0/libgc/include/gc.h 2014-10-07 15:05:25.560975681 +0200
>> @@ -500,7 +500,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_of
>>  #ifdef __linux__
>>  # include <features.h>
>>  # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
>> -     && !defined(__ia64__)
>> +     && !defined(__ia64__) && !defined(__UCLIBC__)
>>  #   ifndef GC_HAVE_BUILTIN_BACKTRACE
>>  #     define GC_HAVE_BUILTIN_BACKTRACE
>>  #   endif
>>
>> This package is based on my previous work that I used regularly on
>> older buildroot versions. The only thing that changed is the bump to
>> mono version 3.8.0.
>>
>> > I am a bit surprised that it works. It is in any case completely wrong,
>> > and there is absolutely no guarantee that uClibc and glibc are ABI
>> > compatible.
>>
>> Based on my limited knowledge of Buildroot internals, it should work
>> because the only toolchain I selected is the one built by buildroot
>> with uClibc 0.9.33.x. Honestly I think that something in between mono
>> cross compilation links erroneously to libc instead to uClibc so the
>> error is explained.
>>
>> I can disable mono when toolchain is uClibc based, but I really want
>> to narrow down and resolve the problem.
>
> Can you push a branch somewhere with all the needed patches + a minimal
> Buildroot configuration that exhibits the problem as well as the
> instructions to test this and reproduce the issue you're seeing?
>
> Thanks,
>
> Thomas
> --
> Thomas Petazzoni, CTO, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com

Comments

Thomas Petazzoni Oct. 9, 2014, 4:02 p.m. UTC | #1
Dear Angelo Compagnucci,

On Thu, 9 Oct 2014 17:58:41 +0200, Angelo Compagnucci wrote:

> Sorry for the reply, but just for the sake of completeness, I rebuilt
> everithing from scratch after pulling latest changes from git.
> 
> I'm running buildroot 2014.11-git-00582-g9951845 with the patch you
> can find attached. Attached you can find also my .config.

Thanks, but I know nothing about Mono, so what command am I supposed to
run on the target to reproduce the issue?

Thanks!

Thomas
Angelo Compagnucci Oct. 9, 2014, 4:40 p.m. UTC | #2
Hi Thomas,

2014-10-09 18:02 GMT+02:00 Thomas Petazzoni
<thomas.petazzoni@free-electrons.com>:
> Dear Angelo Compagnucci,

Angelo could suffice ;) !

> Thanks, but I know nothing about Mono, so what command am I supposed to
> run on the target to reproduce the issue?

Sorry, sometimes I forget my stupidity ...

Attached you can find a minimal mono example.

You can compile it with:

mcs weblient.cs

and run it with

mono webclient.exe http://www.google.com

It should suffice for triggering the error.

Again, thank you!

>
> Thanks!
>
> Thomas
> --
> Thomas Petazzoni, CTO, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
Thomas Petazzoni Oct. 9, 2014, 8:20 p.m. UTC | #3
Angelo,

On Thu, 9 Oct 2014 18:40:05 +0200, Angelo Compagnucci wrote:

> > Thanks, but I know nothing about Mono, so what command am I supposed to
> > run on the target to reproduce the issue?
> 
> Sorry, sometimes I forget my stupidity ...
> 
> Attached you can find a minimal mono example.
> 
> You can compile it with:
> 
> mcs weblient.cs
> 
> and run it with
> 
> mono webclient.exe http://www.google.com
> 
> It should suffice for triggering the error.

It indeed triggers an error here, but not the same as yours:

# mono webclient.exe http://www.google.com

Unhandled Exception:
System.Net.WebException: An error occurred performing a WebClient request. ---> System.NotSupportedException: http://www.google.com/
  at System.Net.WebRequest.GetCreator (System.String prefix) [0x00000] in <filename unknown>:0 
  at System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.GetWebRequest (System.Uri address) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.SetupRequest (System.Uri uri) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.OpenRead (System.Uri address) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Net.WebClient.OpenRead (System.Uri address) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.OpenRead (System.String address) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Net.WebClient:OpenRead (string)
  at Test.Main (System.String[] args) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.WebException: An error occurred performing a WebClient request. ---> System.NotSupportedException: http://www.google.com/
  at System.Net.WebRequest.GetCreator (System.String prefix) [0x00000] in <filename unknown>:0 
  at System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.GetWebRequest (System.Uri address) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.SetupRequest (System.Uri uri) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.OpenRead (System.Uri address) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Net.WebClient.OpenRead (System.Uri address) [0x00000] in <filename unknown>:0 
  at System.Net.WebClient.OpenRead (System.String address) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Net.WebClient:OpenRead (string)
  at Test.Main (System.String[] args) [0x00000] in <filename unknown>:0 

It happens either with webclient.exe built using mcs on the host
machine, or mcs on the target machine.

Another thing I've noticed is that the Mono installation is
*huge*. /usr/lib/mono takes 132 MB. Is all of it necessary?

Also, why do you have two packages, mono-managed and mono-native? One
builds the stuff for the host, and one builds the stuff for the target.
It could simply be one single package called mono, which builds both
for the host and the target.

Thanks,

Thomas
Angelo Compagnucci Oct. 10, 2014, 7:46 a.m. UTC | #4
Hi Thomas,

> It happens either with webclient.exe built using mcs on the host
> machine, or mcs on the target machine.

Yes, right. My fault, you should compile with gmcs that selects the
original 2.0 API version where the error is explicit and not
masquerade inside a nested try/cach.

gmcs mono webclinet.cs
mono webclient.exe http://www.google.com

> Another thing I've noticed is that the Mono installation is
> *huge*. /usr/lib/mono takes 132 MB. Is all of it necessary?

Yes and not! By default mono compiles all the libraries for each one
of the mono versions 2.0, 3.5, 4.0, 4.5, so the most part of the
library is duplicated inside each one of these folders.
You can of course delete which versions is unnecessary for you,
because you can compile against a specific mono library version using
a commandline tag.
If you think it's important, I can update my patch to offer a
selection of which mono version should be shipped into the target
folder, so reducing to the essential the libraries components.
Of course you can further shrink manually your mono installation by
delete libraries that you don't use, but this part is not easily
doable and it's an optimization step that only a software developer
can do basing on his software.

> Also, why do you have two packages, mono-managed and mono-native? One
> builds the stuff for the host, and one builds the stuff for the target.
> It could simply be one single package called mono, which builds both
> for the host and the target.

mono-native compiles the mono virtual machine, but without the
run-time libraries is not useful so much. mono-managed compiles mono
libraries source code (with .cs extension) to the various mono library
versions, but to make that step, a mono compiler must be used.
Probably I can do it inside a qemu instance, using the previously
compiled mono-native, but it will be very slow. Compiling mono library
with mcs on host instead on the target is not so much different,
because the assembly it produces is platform agnostic cause it runs on
mono virtual machine.

Thank you for your time!

>
> Thanks,
>
> Thomas
> --
> Thomas Petazzoni, CTO, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
Thomas Petazzoni Oct. 10, 2014, 10:34 a.m. UTC | #5
Dear Angelo Compagnucci,

On Fri, 10 Oct 2014 09:46:16 +0200, Angelo Compagnucci wrote:

> Yes, right. My fault, you should compile with gmcs that selects the
> original 2.0 API version where the error is explicit and not
> masquerade inside a nested try/cach.
> 
> gmcs mono webclinet.cs
> mono webclient.exe http://www.google.com

Ok, thanks. I could now reproduce the problem.

The fix is pretty simple: edit /etc/mono/config and change the line:

<dllmap dll="libc" target="libc.so.6" os="!windows"/>

to:

<dllmap dll="libc" target="libc.so.0" os="!windows"/>

Then, it doesn't work for http://www.google.com because it redirects to
https://, and there is no SSL/TLS support in the Mono stuff. However,
with a pure http:// URL like http://autobuild.buildroot.org, it works
just fine.

> > Another thing I've noticed is that the Mono installation is
> > *huge*. /usr/lib/mono takes 132 MB. Is all of it necessary?
> 
> Yes and not! By default mono compiles all the libraries for each one
> of the mono versions 2.0, 3.5, 4.0, 4.5, so the most part of the
> library is duplicated inside each one of these folders.
> You can of course delete which versions is unnecessary for you,
> because you can compile against a specific mono library version using
> a commandline tag.
> If you think it's important, I can update my patch to offer a
> selection of which mono version should be shipped into the target
> folder, so reducing to the essential the libraries components.

I believe this would be useful.

> Of course you can further shrink manually your mono installation by
> delete libraries that you don't use, but this part is not easily
> doable and it's an optimization step that only a software developer
> can do basing on his software.

Yes, that's more something left for a post-build script I believe.

> mono-native compiles the mono virtual machine, but without the
> run-time libraries is not useful so much. mono-managed compiles mono
> libraries source code (with .cs extension) to the various mono library
> versions, but to make that step, a mono compiler must be used.
> Probably I can do it inside a qemu instance, using the previously
> compiled mono-native, but it will be very slow. Compiling mono library
> with mcs on host instead on the target is not so much different,
> because the assembly it produces is platform agnostic cause it runs on
> mono virtual machine.

I don't think you understood my comment properly: I do not claim there
is no need for a host package. I claim that you currently have your
host package (mono-managed) separate for the target package
(mono-native) and that this is not needed. They could be both in a
single package called mono, where the host variant of the package
builds the "managed" stuff, and the target variant builds the "native"
stuff. I'll adjust your patch to see if it's indeed possible and if it
is, I'll show you what it looks like.

Thanks,

Thomas
Angelo Compagnucci Oct. 10, 2014, 10:45 a.m. UTC | #6
Hi Thomas!

> The fix is pretty simple: edit /etc/mono/config and change the line:
>
> <dllmap dll="libc" target="libc.so.6" os="!windows"/>
>
> to:
>
> <dllmap dll="libc" target="libc.so.0" os="!windows"/>

This is pretty wonderfull! I totally missed that! I'll include it in a
patch file! May it work also with glibc? If yes, I can tweak a static
version of that file to include.

>>If you think it's important, I can update my patch to offer a
>> selection of which mono version should be shipped into the target
>> folder, so reducing to the essential the libraries components.

> I believe this would be useful.

Great! I'll work on that!

>> Of course you can further shrink manually your mono installation by
>> delete libraries that you don't use, but this part is not easily
>> doable and it's an optimization step that only a software developer
>> can do basing on his software.

> Yes, that's more something left for a post-build script I believe.

Sure, the developer implementing his own software can write a script
to delete all the unneeded libraries.

> I don't think you understood my comment properly: I do not claim there
> is no need for a host package. I claim that you currently have your
> host package (mono-managed) separate for the target package
> (mono-native) and that this is not needed. They could be both in a
> single package called mono, where the host variant of the package
> builds the "managed" stuff, and the target variant builds the "native"
> stuff. I'll adjust your patch to see if it's indeed possible and if it
> is, I'll show you what it looks like.

Yes, Thomas, you caught me, I did not understand your comment!
Actually I really don't know haw to achieve such a dual package in
one, but if you prompt me a minimal example, I'll work on understand
it!

Thank you for your time!

>
> Thanks,
>
> Thomas
> --
> Thomas Petazzoni, CTO, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
Thomas Petazzoni Oct. 10, 2014, 11:06 a.m. UTC | #7
Dear Angelo Compagnucci,

On Fri, 10 Oct 2014 12:45:28 +0200, Angelo Compagnucci wrote:

> > <dllmap dll="libc" target="libc.so.0" os="!windows"/>
> 
> This is pretty wonderfull! I totally missed that! I'll include it in a
> patch file! May it work also with glibc? If yes, I can tweak a static
> version of that file to include.

No, it won't work with glibc, and it most likely won't work with musl
as well. So you'll need to $(SED) this file in a post install target
hook, depending on the C library being used. Since the default value is
OK for glibc, we only need to handle the uClibc and Musl cases. Maybe
something like:

ifeq ($(BR2_TOOLCHAIN_USES_UCLIBC),y)
MONO_LIBC_NAME = libc.so.0
else ifeq ($(BR2_TOOLCHAIN_USES_MUSL),y)
MONO_LIBC_NAME = libc.so
endif

ifneq ($(MONO_LIBC_NAME),)
define MONO_TWEAK_LIBC_NAME
	$(SED) 's,libc.so.6,$(MONO_LIBC_NAME)' $(TARGET_DIR)/etc/mono/config
endef
MONO_POST_INSTALL_TARGET_HOOKS += MONO_TWEAK_LIBC_NAME
endif


> Yes, Thomas, you caught me, I did not understand your comment!
> Actually I really don't know haw to achieve such a dual package in
> one, but if you prompt me a minimal example, I'll work on understand
> it!

I'll have a look.

Thomas
diff mbox

Patch

From 37bb3ccff5c796098bf3805c4858224fcd1f8657 Mon Sep 17 00:00:00 2001
From: Angelo Compagnucci <angelo.compagnucci@gmail.com>
Date: Thu, 9 Oct 2014 15:45:41 +0200
Subject: [PATCH] package/mono: new package

This patch adds the complete Mono implementation. This patch builds
both the native and managed parts.
---
 package/Config.in                                  |  1 +
 package/mono/Config.in                             | 13 +++++++++++
 package/mono/mono-managed/mono-managed.mk          | 25 ++++++++++++++++++++++
 .../mono-native/mono-native-001-fix_uclibc.patch   | 14 ++++++++++++
 package/mono/mono-native/mono-native.mk            | 17 +++++++++++++++
 package/mono/mono.mk                               | 17 +++++++++++++++
 6 files changed, 87 insertions(+)
 create mode 100644 package/mono/Config.in
 create mode 100644 package/mono/mono-managed/mono-managed.mk
 create mode 100644 package/mono/mono-native/mono-native-001-fix_uclibc.patch
 create mode 100644 package/mono/mono-native/mono-native.mk
 create mode 100644 package/mono/mono.mk

diff --git a/package/Config.in b/package/Config.in
index ea89c96..92cf4b8 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -433,6 +433,7 @@  menu "Lua libraries/modules"
 	source "package/xavante/Config.in"
 endmenu
 endif
+	source "package/mono/Config.in"
 	source "package/nodejs/Config.in"
 	source "package/perl/Config.in"
 if BR2_PACKAGE_PERL
diff --git a/package/mono/Config.in b/package/mono/Config.in
new file mode 100644
index 0000000..8bd6d3b
--- /dev/null
+++ b/package/mono/Config.in
@@ -0,0 +1,13 @@ 
+config BR2_PACKAGE_MONO
+	bool "mono"
+	select BR2_STRIP_none
+	depends on (BR2_arm || BR2_armeb || BR2_i386 || BR2_mips \
+		|| BR2_powerpc || BR2_sparc || BR2_x86_64)
+	depends on BR2_INET_IPV6
+	help
+	  An open source, cross-platform, implementation of C# and the CLR that is binary compatible with Microsoft.NET.
+
+	  http://download.mono-project.com/sources/mono/
+
+comment "mono needs a toolchain w/ IPv6"
+	depends on !BR2_INET_IPV6
diff --git a/package/mono/mono-managed/mono-managed.mk b/package/mono/mono-managed/mono-managed.mk
new file mode 100644
index 0000000..b380cf9
--- /dev/null
+++ b/package/mono/mono-managed/mono-managed.mk
@@ -0,0 +1,25 @@ 
+#############################################################
+#
+# mono-managed
+#
+#############################################################
+
+MONO_MANAGED_VERSION = $(MONO_VERSION)
+MONO_MANAGED_SITE = $(MONO_SITE)
+MONO_MANAGED_SOURCE = $(MONO_SOURCE)
+
+HOST_MONO_MANAGED_CONF_OPTS = $(MONO_CONF_OPT) --enable-static \
+	--enable-minimal=aot,profiler
+
+define MONO_MANAGED_GETMONOLITE
+	$(MAKE) -C $(@D) get-monolite-latest
+endef
+
+define MONO_MANAGED_INSTALL
+	rsync -av --exclude=*.so $(HOST_DIR)/usr/lib/mono $(TARGET_DIR)/usr/lib/
+endef
+
+HOST_MONO_MANAGED_POST_CONFIGURE_HOOKS += MONO_MANAGED_GETMONOLITE
+HOST_MONO_MANAGED_POST_INSTALL_HOOKS += MONO_MANAGED_INSTALL
+
+$(eval $(host-autotools-package))
diff --git a/package/mono/mono-native/mono-native-001-fix_uclibc.patch b/package/mono/mono-native/mono-native-001-fix_uclibc.patch
new file mode 100644
index 0000000..c82f24b
--- /dev/null
+++ b/package/mono/mono-native/mono-native-001-fix_uclibc.patch
@@ -0,0 +1,14 @@ 
+Signed-off-by: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+
+diff -purN mono-native-3.8.0.orig/libgc/include/gc.h mono-native-3.8.0/libgc/include/gc.h
+--- mono-native-3.8.0.orig/libgc/include/gc.h	2014-10-07 15:00:21.259466731 +0200
++++ mono-native-3.8.0/libgc/include/gc.h	2014-10-07 15:05:25.560975681 +0200
+@@ -500,7 +500,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_of
+ #ifdef __linux__
+ # include <features.h>
+ # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
+-     && !defined(__ia64__)
++     && !defined(__ia64__) && !defined(__UCLIBC__)
+ #   ifndef GC_HAVE_BUILTIN_BACKTRACE
+ #     define GC_HAVE_BUILTIN_BACKTRACE
+ #   endif
diff --git a/package/mono/mono-native/mono-native.mk b/package/mono/mono-native/mono-native.mk
new file mode 100644
index 0000000..8cea744
--- /dev/null
+++ b/package/mono/mono-native/mono-native.mk
@@ -0,0 +1,17 @@ 
+#############################################################
+#
+# mono-native
+#
+#############################################################
+
+MONO_NATIVE_VERSION = $(MONO_VERSION)
+MONO_NATIVE_SITE = $(MONO_SITE)
+MONO_NATIVE_SOURCE = $(MONO_SOURCE)
+MONO_NATIVE_INSTALL_STAGING = $(MONO_INSTALL_STAGING)
+
+MONO_NATIVE_DEPENDENCIES += host-mono-managed
+
+# Disable managed code (mcs folder) from building
+MONO_NATIVE_CONF_OPTS = $(MONO_CONF_OPT) --disable-mcs-build
+
+$(eval $(autotools-package))
diff --git a/package/mono/mono.mk b/package/mono/mono.mk
new file mode 100644
index 0000000..ff8c2ca
--- /dev/null
+++ b/package/mono/mono.mk
@@ -0,0 +1,17 @@ 
+#############################################################
+#
+# mono
+#
+#############################################################
+
+MONO_VERSION = 3.8.0
+MONO_SITE = http://download.mono-project.com/sources/mono/
+MONO_SOURCE = mono-$(MONO_VERSION).tar.bz2
+MONO_INSTALL_STAGING = YES
+
+MONO_CONF_OPT = --disable-gtk-doc --with-mcs-docs=no --with-moonlight=no
+
+ifeq ($(BR2_PACKAGE_MONO),y)
+	include package/mono/*/*.mk
+	TARGETS += mono-native mono-managed
+endif
-- 
2.1.1