Mono build prob­lems on FreeBSD-​current

I try to build mono on FreeBSD-cur­rent (it is a de­pend­ency of some GNOME pro­gram). Un­for­tu­nately this does not work cor­rectly.

What I see are hangs of the build. If I stop the build when it hangs and re­start it, it will con­tinue and suc­ceed to pro­cess the build steps a little bit fur­ther, but then it hangs again.

If I ktrace the hanging pro­cess, I see that there is a call to wait re­turn­ing with the er­ror mes­sage that the child does not ex­ist. Then there is a call to nanosleep.

It looks to me like this pro­cess missed some SIGCLD (or is wait­ing for some­thing which did not ex­ist at all), and a loop is wait­ing for a child to exit. This loop prob­ably has no proper con­di­tion for the fact that there is no such child (any­more). As such it will stay forever in this loop.

So I grepped a litte bit around in mono and found the fol­low­ing code in <mono-src-dir>/mcs/class/Mono.Posix/Mono.Unix/UnixProcess.cs:

pub­lic void Wait­F­orExit ()
{
    int status;
    int r;
    do {
        r = Nat­ive.Sy­scall.wait­pid (pid, out status, (Native.WaitOptions) 0);
    } while (UnixMarshal.ShouldRetrySyscall ®);
    UnixMarshal.ThrowExceptionForLastErrorIf ®;
}

This does look a little bit as it could be re­lated to the prob­lem I see, but ShouldRetrySy­scall only re­turns true if the er­rno is EINTR. So this looks cor­rect. 🙁

I looked a little bit more at this file and it looks like either I do not un­der­stand the se­mantic of this lan­guage, or Get­Pro­cessStatus does re­turn the re­turn­value of the wait­pid call in­stead of the status (which is not what it shall re­turn to my un­der­stand­ing). If I am cor­rect, it can not really de­tect the status of a pro­cess. It would be very bad if such a fun­da­mental thing went un­noticed in mono…  which does not put a good light on the unit-​tests (if any) or the gen­eral test­ing of mono. For this reason I hope I am wrong.

I did not stop there, as this part does not look like it is the prob­lem. I found the fol­low­ing in mono/io-layer/processes.c:

static gboolean waitfor_​pid (gpointer test, gpointer user_​data)
{
…
    do {
        ret = wait­pid (process->id, &status, WNOHANG);
    } while (er­rno == EINTR); 

if (ret <= 0) { /​* Pro­cess not ready for wait */​ #if­def DEBUG g_​message (“%s: Pro­cess %d not ready for wait­ing for: %s”, _​_​func_​_​, process->id, g_​strerror (er­rno)); #en­dif

re­turn (FALSE); }

#if­def DEBUG g_​message (“%s: Pro­cess %d fin­ished”, _​_​func_​_​, ret); #en­dif

process->waited = TRUE; … } 

And here we have the prob­lem, I think. I changed the (ret <= 0) to  (ret == 0 || (ret < 0 && er­rno != ECHILD)). This will not really give the cor­rect status, but at least it should not block any­more and I should be able to see the dif­fer­ence dur­ing the build.

And now after test­ing, I see a dif­fer­ence, but the prob­lem is still there. The wait with ECHILD is gone in the loop, but there is still some loop with a sem­a­phore op­er­a­tion:

62960 mono     CALL  clock_gettime(0xd,0xbf9feef8)
62960 mono     RET   clock_​gettime 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  nanosleep(0xbf9fef84,0)
62960 mono     RET   nanosleep 0
62960 mono     CALL  clock_gettime(0xd,0xbf9feef8)
62960 mono     RET   clock_​gettime 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  semop(0x20c0000,0xbf9feef6,0x1)
62960 mono     RET   se­mop 0
62960 mono     CALL  nanosleep(0xbf9fef84,0)

OK, there is more go­ing on. I think someone with more know­ledge about mono should have a look at this (do not only look at this se­mop thing, but also look why it loses a child).

StumbleUponXINGBalatarinBox.netDiggGoogle GmailNetvouzPlurkSiteJotTypePad PostYahoo BookmarksVKSlashdotPocketHacker NewsDiigoBuddyMarksRedditLinkedInBibSonomyBufferEmailHatenaLiveJournalNewsVinePrintViadeoYahoo MailAIMBitty BrowserCare2 NewsEvernoteMail.RuPrintFriendlyWaneloYahoo MessengerYoolinkWebnewsStumpediaProtopage BookmarksOdnoklassnikiMendeleyInstapaperFarkCiteULikeBlinklistAOL MailTwitterGoogle+PinterestTumblrAmazon Wish ListBlogMarksDZoneDeliciousFlipboardFolkdJamespotMeneameMixiOknotiziePushaSvejoSymbaloo FeedsWhatsAppYouMobdiHITTWordPressRediff MyPageOutlook.comMySpaceDesign FloatBlogger PostApp.netDiary.RuKindle ItNUjijSegnaloTuentiWykopTwiddlaSina WeiboPinboardNetlogLineGoogle BookmarksDiasporaBookmarks.frBaiduFacebookGoogle ClassroomKakaoQzoneSMSTelegramRenrenKnownYummlyShare/​Save

3 thoughts on “Mono build prob­lems on FreeBSD-​current”

  1. Pingback: Tweets that mention Mono build prob­lems on FreeBSD-current | Alexander Leidinger -- Topsy.com
  2. Hum

    I am afraid you are right and the code in UnixProcess.cs is wrong… May I sug­gest you to open a bug for this in the Novell’s bug tracker?
    https://​bug​zilla​.nov​ell​.com

    Re­gard­ing the prob­lem glob­ally:

    I also did local edits in my svn check­out to com­pile mono with de­bug­ging sup­port but un­for­tu­nately race con­di­tions oc­curs really less of­ten then and de­bug­ging is just harder… So I have not pushed any of these patches in the FreeBSD port. I had al­most the same prob­lem that was triggered by run­ning mono-2.6 (not yet in the ports) and your patch to processes.c seems to solve it too. You can have a look at the bug re­port at nov­ell here:
    https://​bug​zilla​.nov​ell​.com/​s​h​o​w​_​b​u​g​.​c​g​i​?​i​d​=​5​2​8​830

    More test­ing is needed but I think you put your fin­ger at the right loc­a­tion, I have been fooled by the way I dis­covered the prob­lem and though it was a re­gres­sion… Maybe it’s not ac­tualy.

    Which ver­sion of mono are you run­ning ?

    Maybe chat­ting about all this on mono@ is the best place?

    Thanks,
    Ro­main

  3. Pingback: Debugging lang/mono — 2nd round « The Daily BSD

Leave a Reply

Your email address will not be published. Required fields are marked *