/libstdc++.so.6: version `GLIBCXX_3.4.21' not found

I am getting the following error when spawning a child process from a node.js app on a Rasperry Pi with BalenaOS. The child process is a single file downloaded from the internet and stored in a volume. The child process is an express server that serves an angular app.

/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /data-store-volume/downloaded-file)

Here is my Dockerfile for the app container:

FROM resin/raspberrypi3-node:10

COPY catch-connect-client /catch-connect-client

CMD ["/catch-connect-client"]

Also tried this, but same error:

FROM resin/raspberrypi3-node:10

RUN apt-get update && apt-get install -y  libstdc++6

COPY catch-connect-client /catch-connect-client

CMD ["/catch-connect-client"]

I’m not quite sure because the details are ambiguous - is it correct to assume that catch-connect-client is a nodeJS script with a #! header which hints the node interpreter? If so, I can assume it will then attempt to require the script which is in the volume, but this fails to run because of the error you showed above?

I’ve seen this error occur in the past when attempting to run certain nodeJS scripts / npm modules when an npm install was not fully performed, which can sometimes include a compilation / static linking step for the c++ stdlib.

At this point, it’s not quite clear exactly what’s happening from this side. Could you give some more concrete details, such as:

  1. what is in catch-connect-client (specifically, how does it launch the child process)?
  2. how is the child process script’s volume mounted?
  3. what are the contents of the volume?
  4. what’s the full stack trace which leads to that error?

With this information, we’ll be much better able to diagnose the root cause. Cheers!

Also: if the downloaded file is a pre-compiled binary, the issue may be library compatibility between the pre-compiled binary and the base image (resin/raspberrypi3-node:10). The following page seems to have relevant information:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
GCC 5.1.0: GLIBCXX_3.4.21, CXXABI_1.3.9
GCC 5.1.0: libstdc++.so.6.0.21

That seems to have done it. We use zeit/pkg to create the executable on another Raspberry Pi. Building with node v8.x and using FROM resin/raspberrypi3-node:8 was the original issue.

The error does not occur and the app runs when building with node v10.16.0 and using FROM resin/raspberrypi3-node:10.

Thanks for the help @pdcastro and @dt-rush!

Spoke to soon. When building for my previous reply, the angular app was not included in the packaging.

That tells us the problem is with the angular app and not the express app. Building to include the angular app with node10 produces these errors when spawned:

/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /data/theChildBinary)

/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /data/theChildBinary)

It is a node.js app binary built on a Raspberry Pi with zeit/pkg.

const spawnCommand = this.serviceFileLocation;
const parameters = this.spawnParameters;
const options = {
        stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
        execArgv: ['electron .']
 };
 try {
    this.log('Starting child process for service: ' + this.serviceName + ' with file at: ' + this.serviceFileLocation + ' with parameters: ' + parameters);
    this.child = spawn(spawnCommand, parameters, options);}

Not sure if this is what you mean:
version: ‘2.1’
volumes:
catch-connect-client-data:
services:
catch-connect:
build: ./catch-connect
privileged: true
restart: always
volumes:
- ‘data:/data’

The contents of /data is the child binary and a file to persist data

Is it possible for you to do the building of the executable at build time? Alternatively static linking the executable when pre-building might help.

It appears that the version of libc et al is different with the build environment and the base image. I think another thing you could do is pre-build the executable, but from within the same base image that the executable will eventually be executed in.

IMO the best thing in this situation would be to build in the container - this is pretty much what containers were created for.

@CameronDiver

another thing you could do is pre-build the executable, but from within the same base image

That is what we are attempting now, but are running into this error when using pkg:

Warning Failed to make bytecode node10-armv7 for file /snapshot/…

We were missing libraries because we were using an older image.

Updated Dockerfile from:
FROM resin/raspberrypi3-node:10

to;
FROM balenalib/raspberrypi3-node:10

and all is well :slight_smile: