Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mono builds are nondeterministic #20172

Open
bmwiedemann opened this issue Jul 28, 2020 · 6 comments
Open

mono builds are nondeterministic #20172

bmwiedemann opened this issue Jul 28, 2020 · 6 comments

Comments

@bmwiedemann
Copy link
Contributor

While working on reproducible builds for openSUSE, I found that
.exe and .dll files produced by mono differ in every build,
even when reducing environmental differences to a minimum.

Originally filed at https://bugzilla.suse.com/show_bug.cgi?id=1141502

Steps to Reproduce

  1. on openSUSE, install required packages zypper in osc build build-compare mono-devel
  2. build an openSUSE C# package with mono twice osc checkout openSUSE:Factory/smuxi && cd $_ && for n in 1 2 ; do osc build --noservice --keep-pkgs=rpms-$n ; done
  3. compare results /usr/lib/build/pkg-diff.sh rpms-[12]/smuxi-engine-1*noarch.rpm

Current Behavior

.exe and .dll files differ for every build

--- old /usr/lib/smuxi/smuxi-engine.dll (monodis)
+++ new /usr/lib/smuxi/smuxi-engine.dll (monodis)
@@ -52,7 +52,7 @@
 }
 .assembly extern ServiceStack.Text
 {
-  .ver 3:5:7:21894
+  .ver 3:5:7:21932
 }
 .assembly extern System.Xml
 {

Expected Behavior

It should be possible to get bit-identical build results later on another machine.
See https://reproducible-builds.org/ for why this matters.

On which platforms did you notice this

[ ] macOS
[X] Linux
[ ] Windows

Version Used:

mono-devel-6.8.0

The only thing I could find on the topic was https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=851809 and that is probably unrelated.

@akoeplinger
Copy link
Member

You need to make sure to pass the -deterministic option to the C# compiler (csc) to make its output deterministic, however what you see in your case is that you're compiling against different versions of ServiceStack.Text which is a third-party library. My guess is you have a race condition in the build so it compiles against different version accidentally.

@bmwiedemann
Copy link
Contributor Author

In strace of the build I see that no csc is called. Only /usr/lib/mono/4.5/mcs.exe and /usr/lib/mono/xbuild/14.0/bin/xbuild.exe and neither has a -deterministic option documented.

I also try to reduce races by compiling in 1-core-VMs but that seems insufficient here.

@vargaz
Copy link
Member

vargaz commented Aug 10, 2020

The mono build is currently not deterministic:

  • mcs is probably not deterministic it needs a --deterministic flag which computes the assembly guid based on the file contents, same as csc.
  • the runtime executable embeds a timestamp, see mono/mini/buildver-sgen.h.

@bmwiedemann
Copy link
Contributor Author

Here is another testcase in code that might be more familiar:

Comparing mono-addins-1.3.3-0.0.noarch.rpm to mono-addins-1.3.3-0.0.noarch.rpm
comparing the rpm tags of mono-addins
--- old-rpm-tags
+++ new-rpm-tags
@@ -39,7 +39,7 @@
 mono(Mono.Addins.CecilReflector) 32776 1.0.0.0
 mono(Mono.Addins.Gui) 32776 1.0.0.0
 mono(Mono.Addins.Setup) 32776 1.0.0.0
-mono(mautil) 32776 1.0.7527.5251
+mono(mautil) 32776 1.0.7527.5274

--- old /usr/lib/mono/mono-addins/mautil.exe (monodis)
+++ new /usr/lib/mono/mono-addins/mautil.exe (monodis)
@@ -48,7 +48,7 @@
                61 79 4E 61 6D 65 00                            ) // ayName.

   .hash algorithm 0x00008004
-  .ver  1:0:7527:5251
+  .ver  1:0:7527:5274
 }
 .module mautil.exe // GUID = { 42 }

and the difference in the last two version numbers is larger when the time difference between builds is larger. Thanks @vargaz for the pointer to buildver-sgen.h
At least https://github.com/mono/mono/blob/4835e2947/mono/mini/CMakeLists.txt#L767 is already deterministic, because cmake uses SOURCE_DATE_EPOCH for its TIMESTAMP function. But the automake version still needs love.

bmwiedemann added a commit to bmwiedemann/mono that referenced this issue Aug 10, 2020
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

This date call works with different variants of the date command.

Also use UTC to be independent of timezone.

This helps a bit towards deterministic mono builds = issue mono#20172

This PR was done while working on reproducible builds for openSUSE.
bmwiedemann added a commit to bmwiedemann/mono that referenced this issue Dec 22, 2020
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

This date call works with different variants of the date command.

Also use UTC to be independent of timezone.

This helps a bit towards deterministic mono builds = issue mono#20172

This PR was done while working on reproducible builds for openSUSE.
monojenkins pushed a commit to monojenkins/runtime that referenced this issue Dec 22, 2020
Allow to override build date with `SOURCE_DATE_EPOCH`
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

This date call works with different variants of the date command.

Also use UTC to be independent of timezone.

This helps a bit towards deterministic mono builds = issue mono/mono#20172

This PR was done while working on reproducible builds for openSUSE.

<!--
Thank you for your Pull Request!

If you are new to contributing to Mono, please try to do your best at conforming to our coding guidelines http://www.mono-project.com/community/contributing/coding-guidelines/ but don't worry if you get something wrong. One of the project members will help you to get things landed.

Does your pull request fix any of the existing issues? Please use the following format: Fixes #issue-number
-->
akoeplinger pushed a commit that referenced this issue Dec 22, 2020
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

This date call works with different variants of the date command.

Also use UTC to be independent of timezone.

This helps a bit towards deterministic mono builds = issue #20172

This PR was done while working on reproducible builds for openSUSE.
akoeplinger pushed a commit to dotnet/runtime that referenced this issue Dec 22, 2020
Allow to override build date with `SOURCE_DATE_EPOCH`
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

This date call works with different variants of the date command.

Also use UTC to be independent of timezone.

This helps a bit towards deterministic mono builds = issue mono/mono#20172

This PR was done while working on reproducible builds for openSUSE.

Co-authored-by: bmwiedemann <bmwiedemann@users.noreply.github.com>
@bmwiedemann
Copy link
Contributor Author

mcs needs a --deterministic flag

mcs does not have a --deterministic flag - did you mean, someone needs to add it to the mcs code?

buildver-sgen.h non-determinism is fixed in master.

@vargaz
Copy link
Member

vargaz commented Dec 22, 2020

Yes, right now it generates a random GUID and embeds it into the generated assembly. It needs to compute the GUID from the assembly contents instead. Alternatively, the build should use csc which does have a deterministic flag.

bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this issue Apr 3, 2023
https://build.opensuse.org/request/show/1076782
by user iznogood + dimstar_suse
I suspect this app have lost all its users - for one there is no way the twitter integration is still working, second, we are 2 upstream releases behind, yet not a single soul have complained, third current build is not reproduciable due to using mcs and not csc to build (see https://bugzilla.opensuse.org/show_bug.cgi?id=1141502 and upstream mono/mono#20172 )
And last reason (even if this should not matter) Fedorians dropped it 4 years ago
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants