Up to Main Index                          Up to Journal for February, 2020

                   JOURNAL FOR SATURDAY 29TH FEBRUARY, 2020
______________________________________________________________________________

SUBJECT: Go 1.14 and Linux kernel bugs
   DATE: Sat 29 Feb 18:46:50 GMT 2020

Go 1.14 has landed and it looks like I’ve been bitten by bug #37436 [1] which
seems related to bug #35777 [2].

When compiling Go 1.14 I get the following failure:


  crash_test.go:95: testprogcgo CgoCallbackGC exit status: exit status 2
    crash_cgo_test.go:70: expected "OK\n", but got:
        runtime: mlock of signal stack failed: 12
        runtime: increase the mlock limit (ulimit -l) or
        runtime: update your kernel to 5.3.15+, 5.4.2+, or 5.5+
        fatal error: mlock failed


The sad thing is I’m running a 5.4.0-4-amd64 kernel and the fix [3] for the
kernel bug has already been cherry-picked and applied. It seems that Go is
only performing checks for specific kernel versions and not functionality
causing the above Go workaround to kick in — the fact a fix has been
cherry-picked becomes irrelevant :(

neelance has a nice summary [4] which I didn’t find until after I’d gone
through all this myself.

I’ve had to raise the mlock limit, by trial and error, from the default 64kb
to 1024kb. This allows Go 1.14 to compile and all tests to pass.

If you need to raise the mlock limit, as root, edit /etc/security/limits.conf
and add memlock entries for your user (or prefix with an @ for a group), then
log out and in again for changes to take effect. For example:


  diddymus        soft    memlock         64
  diddymus        hard    memlock         4096


The ‘soft’ entry is the default which can be raised up to the ‘hard’ limit
using the ulimit command with the -l switch. For example to set the mlock
limit to 1024 as I did to get Go 1.14 to compile:


  >ulimit -l 1024
  >ulimit -l
  1024
  >


I’m not sure what the implications of this bug are. Do I always need to set
the limit when running Go programs compiled under Go 1.14? Do I need a higher
limit for larger programs, programs that use a lot of goroutines or deep
nested calls? *shrug*

I noticed in the Go 1.14 release notes “Module support in the go command is
now ready for production use, and we encourage all users to migrate to Go
modules for dependency management”. I’m happy using GOPATH without issue and
don’t like modules for a number of reasons. What do other people think? Should
WolfMUD switch to modules?

“How’s WolfMUD doing?” I hear you cry. Well I’ve been feeling somewhat better
and started tackling the issue of being able to ‘puppet’ players. I’ve tried a
few different approaches and still get deadlocks or data races. There doesn’t
seem to be a quick and simple solution.

I think I’m going to have to overhaul the comms and frontend packages. I’m
also thinking the packages should communicate via channels and have a separate
goroutine running a select multiplexer to process the channels. Then either
the network, frontend or game can write commands to the channels.

I’m still playing with a few other ideas first as overhauling the packages is
quite a bit of work.

--
Diddymus

  [1] Go #37436 runtime: mlock of signal stack failed: 12
        https://github.com/golang/go/issues/37436

  [2] Go #35777 runtime: memory corruption on Linux 5.2+
        https://github.com/golang/go/issues/35777

  [3] x86/fpu: Don’t cache access to fpu_fpregs_owner_ctx
        https://git.kernel.org/tip/59c4bd853abcea95eccc167a7d7fd5f1a5f47b98

  [4] Summary of issue from neelance:
        https://github.com/golang/go/issues/37436#issuecomment-591327351


  Up to Main Index                          Up to Journal for February, 2020