go: build: dyld: Symbol not found: _fdopendir$INODE64 on OS X 10.9 Mavericks

What version of Go are you using (go version)?

go1.13.3.darwin-amd64.tar.gz

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

OS X 10.9.5 Build 13F34

What did you do?

Running OS X 10.9.5 Build 13F34, downloaded go1.13.3.darwin-amd64.tar.gz. Trying to run it

What did you expect to see?

Working go command

What did you see instead?

sh-3.2# export PATH=$PATH:/usr/local/go/bin
sh-3.2# go
go             gobject-query  gofmt          
sh-3.2# go
dyld: Symbol not found: _fdopendir$INODE64
  Referenced from: /usr/local/go/bin/go
  Expected in: flat namespace

Trace/BPT trap: 5

Before this is closed with “too old OS version”: One of the main advantages of Go imho is that it is statically compiled and hence should run independent from the libraries shipped with the OS. Hence it would be highly appreciated if this could be made work, or at least explained why it is not possible.

It used to work in

sh-3.2# go version
go version go1.10.8 darwin/amd64

What has changed to make this no longer work?

Could https://github.com/macports/macports-legacy-support be used to fix this, especially https://github.com/macports/macports-ports/commit/abe46d0764f08fdec9a4923880ce03edbc768a0d?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 27 (15 by maintainers)

Most upvoted comments

the simplest thing to do is probably to automatically wrap go binaries in a launch script that sets the proper environment variables. We already have a number of workarounds that work this way on MacPorts. If this is reliable enough to do generally, we’ll open a PR for it, using one of our other similar workarounds as a template.

go 1.15 and programs built with it run fine on OSX 10.9 Mavericks using the latest macports-legacy-support library and DYLD_INSERT_LIBRARIES: https://github.com/evanw/esbuild/issues/81#issuecomment-680147925. It might work with older OS versions, but I haven’t tried.

Hi. Yes – in MacPorts, one of our members, @Ionic , has been working with this with some success. https://github.com/macports/macports-ports/blob/52f3f71c33a430c6046efdddf9cce347ae2de3db/lang/go/Portfile#L68 . It currently does require a manual step to enable linking in the legacysupport library that contains the extra functions that perhaps we might automate one day.

@Ionic has also been working on an enhanced version of this of late, https://trac.macports.org/ticket/58935 that we are / I am just trying to fully wrap my head around. But it is do-able, it appears.

Makes a big difference for me personally: The difference is whether my 2007 Mac is a feasible system or a pile of junk. Because Apple stopped supporting it 4 or so macOS releases ago. Please be mindful of our environment and don’t add to this kind of forced electronic waste.

That’s not upstream’s job, though. I can speak with both upstream and downstream hats on. Supporting legacy, unsupported (by their vendor), insecure operating systems with missing functionality is a pain for upstream developers.

That’s why downstream package management systems exist. They take upstream’s base and modify it to work on their (and their user’s) systems. This is also true for MacPorts, which patches software (like go) for such older systems on a voluntary(!) basis to also support legacy systems, if reasonably possible.

And wait, didn’t Apple Marketing brag that macOS was fully UNIX 03-compliant? Apparently, Apple obtained UNIX 03 certification with OS X 10.5. So, if Go uses that, wouldn’t it have to work? Apple can’t just deprecate stuff at will.

Yes, they went through the process. But neither the syscall function nor the fdopendir function are part of SUSv3. SUS defines functions, but leaves the details (e.g., as syscalls xor library functions) to the implementation.

fdopendir made its debut in SUSv4, so it’s not surprising that older OS X systems don’t support it.

The only thing Apple did deprecate was internal implementation details - and that’s totally fine.

Systems and specifications evolve over time.

There is no way to add a required library, and there is no simple way of adding that functionality.

That’s unfortunate, but…

As I suggested earlier in #35269 (comment), there is no list of libraries to link against. There is a list of specific symbols and the libraries from which they come.

I guess I could try to patch this instead and pull in the support library. Would need to test this, but I figure that could be a lot more complicated then it initially sounds and downright impossible.

I’m inclined to close this issue since I don’t think the Go team is going to take any action here.

Honestly, sounds fine to me.

without a clear gain - especially since Apple officially only supports the current OS release and at most the two most recent previous ones, or something along those lines

Makes a big difference for me personally: The difference is whether my 2007 Mac is a feasible system or a pile of junk. Because Apple stopped supporting it 4 or so macOS releases ago. Please be mindful of our environment and don’t add to this kind of forced electronic waste.

And wait, didn’t Apple Marketing brag that macOS was fully UNIX 03-compliant? Apparently, Apple obtained UNIX 03 certification with OS X 10.5. So, if Go uses that, wouldn’t it have to work? Apple can’t just deprecate stuff at will.

Is this certification worth anything or is it just a worthless piece of paper?

The issue isn’t the suffix. (Or to be more precise: the missing suffix is only an implementation issue in MacportsLegacySupport. That’s a solved issue, I just need to follow up on that.)

The issue is that the function is not provided on older Darwin versions at all.

What Ken was asking for was a way to specify other external libraries to be linked to for all operations by go itself.

My current workaround forces an external linker and passing custom external linker flags (essentially -L... and -lLegacySupport), but that’s not “automagic” or transparent. Any go user would need to explicitly enable external linking and pass these flags manually in order to obtain working go programs - even after the binary has been built and installed successfully.

It was, however, the only way to do something like this I could find. Maybe there’s a better way, though. One which works automatically, even after go was built/installed and particularly one that doesn’t require an external linker.

You are correct: the decision to drop support for older macOS releases was not made for technical reasons. We have limited resources. We do not want to support releases for which we do not run builders. We do not want to run builders for releases that are not receiving security updates. So we chose to drop support.

The only thing I know of that technically prevents the latest Go versions from running on old macOS versions is this issue that you have just filed. If you want to analyze this issue and find a fix and send in the fix, we would probably consider it if it is not too invasive. But we do not consider ourselves responsible for fixing the issue. We prefer to focus our limited resources on newer versions. We aren’t even running the old systems that we would need to run to analyze and test any fix.

Older versions of Go should continue to work fine on older versions of macOS.

I’m sorry that this is likely not the answer you want to hear, but I think it is better to be realistic about what we can accomplish.

Not everyone can run the latest versions of macOS for various reasons. I would like to know what is technically preventing the latest Go versions to work on older Mac OS X and OS X versions.