awslabs/aws-lambda-cpp

Compilation fails on latest Alpine Linux (missing execinfo.h)

cmil opened this issue ยท 14 comments

cmil commented

Reproducing the build instructions in the README with the following Dockerfile

FROM alpine:3.14

RUN apk add git g++ make cmake unzip libtool curl-dev automake

RUN git clone https://github.com/awslabs/aws-lambda-cpp.git && \
cd aws-lambda-cpp && \
mkdir build && \
cd build && \
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/lambda-install && \
make && make install

and running

docker build -t aws-lambda-cpp .

I get

#6 0.266 Cloning into 'aws-lambda-cpp'...                                                                                               
#6 1.134 -- The CXX compiler identification is GNU 10.3.1                                                                               
#6 1.148 -- Detecting CXX compiler ABI info                                                                                             
#6 1.220 -- Detecting CXX compiler ABI info - done
#6 1.236 -- Check for working CXX compiler: /usr/bin/c++ - skipped
#6 1.237 -- Detecting CXX compile features
#6 1.238 -- Detecting CXX compile features - done
#6 1.460 -- Found CURL: /usr/lib/libcurl.so (found version "7.77.0")  
#6 1.470 -- Configuring done
#6 1.474 -- Generating done
#6 1.475 -- Build files have been written to: /aws-lambda-cpp/build
#6 1.500 [ 20%] Building CXX object CMakeFiles/aws-lambda-runtime.dir/src/logging.cpp.o
#6 1.630 [ 40%] Building CXX object CMakeFiles/aws-lambda-runtime.dir/src/runtime.cpp.o
#6 2.250 [ 60%] Building CXX object CMakeFiles/aws-lambda-runtime.dir/src/backward.cpp.o
#6 2.340 In file included from /aws-lambda-cpp/src/backward.cpp:26:
#6 2.340 /aws-lambda-cpp/src/backward.h:245:18: fatal error: execinfo.h: No such file or directory
#6 2.340   245 | #        include <execinfo.h>
#6 2.340       |                  ^~~~~~~~~~~~
#6 2.341 compilation terminated.
#6 2.344 make[2]: *** [CMakeFiles/aws-lambda-runtime.dir/build.make:104: CMakeFiles/aws-lambda-runtime.dir/src/backward.cpp.o] Error 1
#6 2.344 make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/aws-lambda-runtime.dir/all] Error 2
#6 2.344 make: *** [Makefile:136: all] Error 2

What's missing?

@cmil Hi cmil, I also encounter the same issue, and I add tried package ( RUN apk add libexecinfo-dev ) and another compile error come out ( Dl_info undefine ) . so far luck to continue.

May I know which version of alpine you use can pass the compile ?

@cmil Hi cmil, I also encounter the same issue, and I add tried package ( RUN apk add libexecinfo-dev ) and another compile error come out ( Dl_info undefine ) . so far luck to continue.

May I know which version of alpine you use can pass the compile ?

Apparently Dl_info is part of glibc, which is not included in Alpine Linux anymore, as it has been replaced with musl.

https://alpinelinux.org/posts/Alpine-Linux-has-switched-to-musl-libc.html

Looks like it can still be installed manually (not with apk add) but in my case it was easier to just use the amazonlinux Docker image as the base image (I've used v2 without issues).

I got to exactly the same point by doing apk add libexecinfo-dev.

[ 20%] Building CXX object CMakeFiles/aws-lambda-runtime.dir/src/logging.cpp.o
[ 40%] Building CXX object CMakeFiles/aws-lambda-runtime.dir/src/runtime.cpp.o
[ 60%] Building CXX object CMakeFiles/aws-lambda-runtime.dir/src/backward.cpp.o
In file included from /home/aws-lambda-cpp/src/backward.cpp:26:
/home/aws-lambda-cpp/src/backward.h:1066:35: error: 'Dl_info' has not been declared
 1066 |     std::string resolve_exec_path(Dl_info& symbol_info) const
      |                                   ^~~~~~~
/home/aws-lambda-cpp/src/backward.h: In member function 'std::string backward::TraceResolverLinuxBase::resolve_exec_path(int&) const':
/home/aws-lambda-cpp/src/backward.h:1070:25: error: request for member 'dli_fname' in 'symbol_info', which is of non-class type 'int'
 1070 |         if (symbol_info.dli_fname == argv0_) {
      |                         ^~~~~~~~~
/home/aws-lambda-cpp/src/backward.h:1077:25: error: request for member 'dli_fname' in 'symbol_info', which is of non-class type 'int'
 1077 |             symbol_info.dli_fname = "/proc/self/exe";
      |                         ^~~~~~~~~
/home/aws-lambda-cpp/src/backward.h:1081:32: error: request for member 'dli_fname' in 'symbol_info', which is of non-class type 'int'
 1081 |             return symbol_info.dli_fname;
      |                                ^~~~~~~~~

It looks like Dl_info is a structure that is present in musl, and is exported by dlfcn.h, same as glibc, and libexecinfo also uses it.

The issue is that dlfcn.h isn't being included in src/backward.h when building on Alpine.

The compiler gets to this point without having included it, but it is required:

# if (BACKWARD_HAS_BACKTRACE == 1) || (BACKWARD_HAS_BACKTRACE_SYMBOL == 1)
// then we shall rely on backtrace
# include <execinfo.h>
# endif

Should be fixed now.

Also, add "execinfo" to your target_link_libraries() in CMakeLists.txt in your project so that it links against libexecinfo.

This problem has been noted at the AWS C Common project: awslabs/aws-c-common#322

That project ended up making execinfo.h entirely optional.

Perhaps it would make sense to make backtrace support optional, and print a message suggesting to install libexecinfo to get support if you don't have it.

Fails on latest alpine, anyone happen to know what package to use instead of libexecinfo-dev or another fix?

mandric in ~/dev/github.com/awslabs/aws-lambda-cpp/examples (master=)                                                            
$ docker build -t test .
[+] Building 11.1s (5/5) FINISHED                                                                                                
 => [internal] load build definition from Dockerfile                                                                        0.0s
 => => transferring dockerfile: 147B                                                                                        0.0s
 => [internal] load .dockerignore                                                                                           0.0s
 => => transferring context: 2B                                                                                             0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                            3.8s
 => [1/2] FROM docker.io/library/alpine:latest@sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4      0.0s
 => => resolve docker.io/library/alpine:latest@sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4      0.0s
 => => sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4 1.64kB / 1.64kB                              0.0s
 => => sha256:c0d488a800e4127c334ad20d61d7bc21b4097540327217dfab52262adc02380c 528B / 528B                                  0.0s
 => => sha256:49176f190c7e9cdb51ac85ab6c6d5e4512352218190cd69b08e6fd803ffbf3da 1.47kB / 1.47kB                              0.0s
 => ERROR [2/2] RUN apk add --no-cache cmake make g++ git bash zip curl-dev zlib-dev libexecinfo-dev                        6.7s
------                                                                                                                           
 > [2/2] RUN apk add --no-cache cmake make g++ git bash zip curl-dev zlib-dev libexecinfo-dev:                                   
#4 0.499 fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz                                           
#4 2.904 fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz                                      
#4 6.593 ERROR: unable to select packages:                                                                                       
#4 6.635   libexecinfo-dev (no such package):
#4 6.635     required by: world[libexecinfo-dev]
------
executor failed running [/bin/sh -c apk add --no-cache cmake make g++ git bash zip curl-dev zlib-dev libexecinfo-dev]: exit code: 1

It looks like other projects are running into the same issue (DataDog/dd-trace-php#1824, dmlc/xgboost#8595) that the libexecinfo-dev package is no longer present in Alpine 3.17:

Does it mean no more backtrace support in Alpine?

FYI: Succeeded in installing on Alpine 3.17 by providing libdw (using elfutils(-dev) package).

worked for me too...

diff --git a/examples/Dockerfile b/examples/Dockerfile
index 1aabd59..87d4bcf 100644
--- a/examples/Dockerfile
+++ b/examples/Dockerfile
@@ -1,3 +1,3 @@
 FROM alpine:latest
 
-RUN apk add --no-cache cmake make g++ git bash zip curl-dev zlib-dev libexecinfo-dev
+RUN apk add --no-cache cmake make g++ git bash zip curl-dev zlib-dev elfutils-dev

Note that elfutils-dev and libexecinfo-dev are not always interchangeable. The elfutils-dev gave me cmake error at build time.

found this comment explaining how to install libexecinfo - aws/aws-lambda-nodejs-runtime-interface-client#68 (comment)

works "beautifully"

Dockerfile
FROM alpine

RUN \
    apk add --virtual builders git g++ make cmake unzip libtool curl-dev automake && \
    apk add --repository=https://dl-cdn.alpinelinux.org/alpine/v3.16/main/ libexecinfo-dev && \
    git clone --depth 1 https://github.com/awslabs/aws-lambda-cpp.git && \
    cd aws-lambda-cpp && \
    mkdir build && \
    cd build && \
    cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/lambda-install && \
    make && make install && \
    apk del builders

unfortunately does not do much to remedy the awful aws/aws-lambda-nodejs-runtime-interface-client#16 situation - at least not on its own