Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building native images with quarkus.native.container-build=true and quarkus.native.debug.enabled=true depends on host tools for splitting the debug info #13754

Closed
zakkak opened this issue Dec 8, 2020 · 4 comments · Fixed by #13963
Assignees
Labels
kind/bug Something isn't working
Milestone

Comments

@zakkak
Copy link
Contributor

zakkak commented Dec 8, 2020

Describe the bug
Currently, when using quarkus.native.container-build=true in combination with quarkus.native.debug.enabled=true Quarkus uses the container image to build the native image but relies on the host to provide the objcopy utility to split the debug info from the native image. Since the purpose of using a container image is to avoid having to install specific tooling on the host, this results in bad user experience (see #13517).

Expected behavior
Users shouldn't need to install anything special/extra on the host to build native images when using quarkus.native.container-build=true.

Actual behavior
Users need to make sure objcopy is available on the host (see #13517).

To Reproduce

On a system without objcopy installed run:

mvn io.quarkus:quarkus-maven-plugin:1.9.2.Final:create     -DprojectGroupId=org.acme     -DprojectArtifactId=getting-started     -DclassName="org.acme.getting.started.GreetingResource"     -Dpath="/hello"
cd getting-started
mvn dependency:sources
mvn clean package -Dquarkus.native.container-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel:20.2-java11 -Dnative -Dquarkus.native.debug.enabled=true
ls target/getting-started-1.0-SNAPSHOT-runner.debug  ## not present when using macOS for the docker based build

(Mostly copied from #13517)

Configuration

quarkus.native.container-build=true
quarkus.native.debug.enabled=true

Additional context
Possible approaches to solving this:

1. Since the container image is currently defined to run native-image we could extend native-image to accept a flag that dumps the symbols in a separate .debug file.

This benefits both GraalVM users and Quarkus users but it will need to go through upstream Graal and it will take some time to make it to Quarkus.

2. We can use the container image to actually call objcopy in some "ugly" way.

E.g.:

podman run --rm --user $(id -u):$(id -u) --userns=keep-id --entrypoint /bin/bash quay.io/quarkus/ubi-quarkus-mandrel:20.2-java11 -c "objcopy --version"

This seems the most straight forward approach and will be directly accessible.

3. Change the container image to use as the entrypoint a wrapper script instead of native-image

This will move the objcopy part out of Quarkus' source code for the case of quarkus.native.container-build=true but it will still require the logic to be present for native builds on the host system.

@zakkak zakkak added the kind/bug Something isn't working label Dec 8, 2020
@ghost ghost added the area/mandrel label Dec 8, 2020
@ghost
Copy link

ghost commented Dec 8, 2020

/cc @galderz

@jerboaa
Copy link
Contributor

jerboaa commented Dec 9, 2020

Additional context
Possible approaches to solving this:

1. Since the container image is currently defined to run native-image we could extend native-image to accept a flag that dumps the symbols in a separate .debug file.

This benefits both GraalVM users and Quarkus users but it will need to go through upstream Graal and it will take some time to make it to Quarkus.

It would likely introduce a dependency for Graal so as to be able to do the stripping. Note that graal might have different user needs, but perhaps it should be discussed upstream. I'm not sure what the outcome of such discussion would be.

2. We can use the container image to actually call objcopy in some "ugly" way.

E.g.:

podman run --rm --user $(id -u):$(id -u) --userns=keep-id --entrypoint /bin/bash quay.io/quarkus/ubi-quarkus-mandrel:20.2-java11 -c "objcopy --version"

I'm +1 on this, if we've got the container flag set, objcopy should be changed to be podman run --rm --user $(id -u):$(id -u) --userns=keep-id --entrypoint /usr/bin/objcopy <image-name> (with possible volume mounts) instead. It's good symmetry to what is being done for the native-image invocation itself, no? The arguments to objcopy remain the same (I think) more or less.

This seems the most straight forward approach and will be directly accessible.

3. Change the container image to use as the entrypoint a wrapper script instead of native-image

This will move the objcopy part out of Quarkus' source code for the case of quarkus.native.container-build=true but it will still require the logic to be present for native builds on the host system.

I believe we've discussed option 3) before and opted against it. There did even exist a prototype. The reason why it was rejected, eludes me now. But I think it was considered something quarkus should be driving (the post-processing), not graal itself.

@zakkak
Copy link
Contributor Author

zakkak commented Dec 10, 2020

Thanks for the input Severin.

It would likely introduce a dependency for Graal so as to be able to do the stripping. Note that graal might have different user needs, but perhaps it should be discussed upstream. I'm not sure what the outcome of such discussion would be.

AFAIU native-image should be able to directly create the .debug file without first embedding the debug info in the executable and then splitting it. As a result no external dependencies should be required to achieve this.

I opened oracle/graal#3056 to get the discussion going.

@jerboaa
Copy link
Contributor

jerboaa commented Dec 10, 2020

Thanks for the input Severin.

It would likely introduce a dependency for Graal so as to be able to do the stripping. Note that graal might have different user needs, but perhaps it should be discussed upstream. I'm not sure what the outcome of such discussion would be.

AFAIU native-image should be able to directly create the .debug file without first embedding the debug info in the executable and then splitting it. As a result no external dependencies should be required to achieve this.

Hmm, OK. It sounds a bit like re-inventing the wheel to me, though. binutils[1] does a fine job on this and has been around for years and is stable, fwiw.

I opened oracle/graal#3056 to get the discussion going.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working
Projects
None yet
2 participants