Search code examples
c++linuxdockerfilegrpcapache-arrow

Missing output or input when running c++ binary in docker


Building a cpp binary inside a docker builder with cmake

FROM ubuntu:focal as builder
WORKDIR /var/lib/project
RUN cmake ... && make ...

Then copying the built binary to final image which also is ubuntu:focal, to a WORKDIR.

WORKDIR /var/lib/project

COPY --from=builder /usr/src/project/bin/binary ./binary

EXPOSE 8080

CMD ["./binary"]

Running the docker with docker run hangs the docker (even with -d), no input and output. To stop the docker, I have to kill it from another terminal. However, if I exec into that same container while it is hanging, and run the binary from the shell inside the docker, it will work as expected.

Command used to build the docker

docker build . --platform=linux/amd64 --file docker/Dockerfile --progress=plain -c 32 -t mydocker:latest

Tried:

CMD ["/bin/bash", "-c" , "./binary"]
CMD ["/bin/bash", "-c" , "exec", "./binary"]

And same configurations with ENTRYPOINT too. Same behavior.

I'm guessing there is a problem with how the binary is built, maybe some specific flags are needed, because if I do docker run ... ls or any other built in command it will work and output to my stdout.

Expecting to have my binary std* redirected to my std* just like any other command inside docker.

There is another related question, as of now, unanswered.

Update: Main binary is built with these

CXX_FLAGS= -fno-builtin-memcmp -fPIC -Wfatal-errors -w -msse -msse4.2 -mavx2

Update: Main part of the binary code, The version is apache arrow 10.0.1

int main() {
   arf::Location srv_loc = arf::Location::ForGrpcTcp("127.0.01", 8080).ValueUnsafe();
   arf::FlightServerOptions opt(srv_loc);
   auto server = std::make_unique<MyService>();
   ARROW_RETURN_NOT_OK(server->Init(opt));
   std::printf("Starting on port: %i\n", server->port());
   return server->Serve().ok();
}

UPDATE: The problem seems to be here:

While the container is hanging, I entered into it, and did a ps aux. The binary gets PID=1, I don't know why this happens, but hardly this is the correct behavior.

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.2  0.0 341520 13372 ?        Ssl  07:52   0:00 ./binary
root          12  0.5  0.0   4116  3412 pts/0    Ss   07:52   0:00 /bin/bash
root          20  0.0  0.0   5900  2884 pts/0    R+   07:52   0:00 ps aux

UPDATE: ./binary is executable, chmod +x is useless.

Adding printfs to multiple places did not work, unless the last line server->Serve() is commented out, or prints are really large, then everything gets printed.

Separating return statement from server->Server() makes no difference.

UPDATE:

Running the built container with docker --init -d flag, works. Tough is this the right way? and if so how can this be forced in dockerfile?


Solution

  • This problem is related to the pid of the process in the container. You can use the --init flag to avoid the problem. for more information visit this site- https://docs.docker.com/engine/reference/run/#specify-an-init-process