Segmentation violation when running ROOT based application as snap package

Hi,
I have a ROOT based c++ application which I use to run as snap package. The snap package builds correctly, so I’m confident that all dependencies are there.

When I launch my application I get this:

error: entry with relative path at the root level is not discoverable
{ 'name': '', 'type': 'directory',
          ^~
Error in modulemap.overlay!

 *** Break *** segmentation violation
 Generating stack trace...
 0x00007f1af1649a7d in <unknown> from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1af164beb1 in <unknown> from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1af164d8c4 in cling::CIFactory::createCI(llvm::StringRef, cling::InvocationOptions const&, char const*, std::unique_ptr<clang::ASTConsumer, std::default_delete<clang::ASTConsumer> >, std::vector<std::shared_ptr<clang::ModuleFileExtension>, std::allocator<std::shared_ptr<clang::ModuleFileExtension> > > const&) + 0xa4 from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1af171914f in cling::IncrementalParser::IncrementalParser(cling::Interpreter*, char const*, std::vector<std::shared_ptr<clang::ModuleFileExtension>, std::allocator<std::shared_ptr<clang::ModuleFileExtension> > > const&) + 0x24f from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1af16834ef in cling::Interpreter::Interpreter(int, char const* const*, char const*, std::vector<std::shared_ptr<clang::ModuleFileExtension>, std::allocator<std::shared_ptr<clang::ModuleFileExtension> > > const&, bool, cling::Interpreter const*) + 0x26f from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1af15aed2d in <unknown> from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1af15b04d0 in CreateInterpreter + 0x30 from /snap/app/x1/plot/linux/bin/libCling.so
 0x00007f1aff19f64c in TROOT::InitInterpreter() + 0xdc from /snap/app/x1/plot/linux/bin/libCore.so
 0x00007f1aff19fbcf in ROOT::Internal::GetROOT2() + 0x2f from /snap/app/x1/plot/linux/bin/libCore.so
 0x00007f1aff1ade0d in TApplication::TApplication(char const*, int*, char**, void*, int) + 0x24d from /snap/app/x1/plot/linux/bin/libCore.so

Does anyone know what’s happening?
I have no problem if I simply compile and run my application without using snap.

Can you provide some more information on what you’ve got set up? Ideally providing the build files might provide some insights into what could be possibly going wrong. I can see there’s a reference to /snap/app/x1, so that suggests you likely have your own snapcraft.yaml.

For reference for something that’s a bit more than “just” ROOT in a snap, you might be interested in looking at Gate, which has its own isolated ROOT, Geant4, and QT, so might approximate your own scenario a bit better than the root-framework snap directly.

My guess here, given that it works outside the snap environment, is that this is possibly a case of ABI incompatibility, such as if for example you were adding binaries generated outside the snap build environment (e.g, on the host itself)

1 Like

Thank you for your reply.

Yes I have my own snapcraft.yaml, but I just use the ‘dump’ plugin with a pre-built tar.gz package with my application. This tar.gz is what I use when I say that I can run it outside snap without problems.

Maybe your guess is right, I’ve included in this tar.gz package the needed ROOT libraries, generated on the host itself. As you see from the error messages, all libraries are inside plot/linux/bin

This way of building my snap was previously working when I was using ROOT 5.34, but now I see this error after moving to ROOT 6.24.

I’ve not been around ROOT long enough to know just how much changed between ROOT 5 and ROOT 6, but treating this as purely a snap specific problem rather than a ROOT specific problem, the dump plugin implicitly expects either content that doesn’t have any concerns about binary compatibility, or that the content is already compatible with the base snap and the rest of the snap.

If your snap uses the core 20 base, but the dump plugin content was built on Ubuntu 21.10, it’s expected that this would cause issues. Similarly, if you base on core 20 but built on Ubuntu 18.04, there’s issues there too.

Depending on the application, things might work anyway, or only break subtly. But speaking from a general viewpoint, it’s basically impossible to provide any guarantees. It’s why if you look at the ROOT downloads page there’s a different pre-compiled version for every major Ubuntu version (equivilently so for other distributions). And in the case of ROOT 6, it looks like the breakages aren’t minor at all unfortunately.

The best solution would be to build ROOT and your extras in the snapcraft environment itself, e.g, via the cmake plugin, the output will then be compatible with each other properly. If you want to continue using the dump plugin, then you’d need to consider using a virtual machine/container to ensure that the binaries are built on a matching platform.

(ROOT 5 and ROOT 6 are very different beasts, especially in terms of build system)

Ok I understand your point.
Of course I payed attention to compatibility between the snap base and the archive content. It is built on Ubuntu 18.04 (both ROOT and my application which uses it), and then I use core18 as base for the snap.

I will try the suggestion to build everything in the snapcraft environment, this is for sure the cleanest way to proceed.

Thanks also for pointing me to Gate, it could be for sure a good example.

Since you were correctly building on a matching platform, the problem likely shifts over to a more general case of missing packages/ environment variables/ layouts. It’s possible that your host had packages installed that implicitly enabled different features / dependencies, and that the runtime environment was lacking these equivilents. With ROOT, the build environment and runtime environment aren’t clearly separated in the same way most other applications are, so a reproducible build environment is just as important as the reproducible runtime environment. It’s why there’s a need to include *-dev packages in stage-packages, even though for the vast majority of snaps, this would be considered a waste of disk space for no gain.

Hopefully simply building internally would help in this case then, but if it doesn’t fix the problem directly, it should at least provide a lot more guarantees about how ROOT is being built that would make diagnosing the issue hopefully a lot easier, and perhaps even as simple as just staging the right packages and ensuring they’re in $LD_LIBRARY_PATH.

I’ve made a simple test, just to remove variables and better isolate the problem.
I’ve downloaded the last ROOT package, for Ubuntu 18.04, root_v6.24.06.Linux-ubuntu18-x86_64-gcc7.5.tar.gz.
Then, this is my simple and minimal snapcraft.yaml

name: test
base: core18
version: '1.0'
summary: test
description: test
grade: devel
confinement: devmode
architectures: [amd64]

parts:
  test:
    plugin: dump
    source: root_v6.24.06.Linux-ubuntu18-x86_64-gcc7.5.tar.gz
    stage-packages: 
      - libxpm-dev
      - libxext-dev
      - g++

apps:
  test:
    command: bin/root
    plugs: [home, x11, opengl, network, unity7]

After building this snap and installing it, I run it with the command test, but I get the same error:

error: entry with relative path at the root level is not discoverable
{ 'name': '', 'type': 'directory',
          ^~
Error in modulemap.overlay!

 *** Break *** segmentation violation
 Generating stack trace...
 0x00007fdff7bfeb8d in <unknown> from /snap/test/x1/lib/libCling.so
 0x00007fdff7c00fa1 in <unknown> from /snap/test/x1/lib/libCling.so
 0x00007fdff7c029b4 in <unknown> from /snap/test/x1/lib/libCling.so
 0x00007fdff7cd1caf in <unknown> from /snap/test/x1/lib/libCling.so
 0x00007fdff7c39650 in <unknown> from /snap/test/x1/lib/libCling.so
 0x00007fdff7b693f8 in TCling::TCling(char const*, char const*, char const* const*) + 0xff8 from /snap/test/x1/lib/libCling.so
 0x00007fdff7b6ac50 in CreateInterpreter + 0x30 from /snap/test/x1/lib/libCling.so
 0x00007fdffdead80c in TROOT::InitInterpreter() + 0xdc from /snap/test/x1/lib/libCore.so.6.24
 0x00007fdffdeadd8f in ROOT::Internal::GetROOT2() + 0x2f from /snap/test/x1/lib/libCore.so.6.24
 0x00007fdffdebbfcd in TApplication::TApplication(char const*, int*, char**, void*, int) + 0x24d from /snap/test/x1/lib/libCore.so.6.24
 0x00007fdffe443feb in TRint::TRint(char const*, int*, char**, void*, int, bool) + 0x3b from /snap/test/x1/lib/libRint.so.6.24
 0x000055c032fa1a60 in main + 0x40 from /snap/test/x1/bin/root.exe
 0x00007fdffd3adbf7 in __libc_start_main + 0xe7 from /lib/x86_64-linux-gnu/libc.so.6
 0x000055c032fa1aca in _start + 0x2a from /snap/test/x1/bin/root.exe

Try:

stage-packages: 
  - g++
  - gcc
  - libstdc++6
  - libstc6-dev
  - libxpm-dev
  - libxext-dev
  - libx11-dev
  - libxft-dev
  - libpng
  - libjpeg
  - libssl-dev
  - libglu1-mesa

Strictly speaking, I don’t think it is necessary to include gcc and g++, since from what I’ve tested this mostly only effects ACliC functionality, but I’ve included them to be sure.
These dependencies from the pre-compiled packages page are still essential in the snap runtime.

You’ll also need to set up a layout so that the headers can be found in their expected location

layout:
  /usr/include:
    bind: $SNAP/usr/include

At this point it would likely start working, but depending on your use case, there’s possibly still more setup.

For example, it might be helpful to set environment variables such as $ROOTSYS, you need to set LANG: C.UTF-8 to fix errors with strings being printed with error messages. You may need to set $LD_LIBRARY_PATH to also include ROOT’s lib folder.

environment:
  LANG: C.UTF-8
  ROOTSYS: $SNAP/path/to/root
  LD_LIBRARY_PATH: $SNAP/path/to/root/lib

You may need to run a wrapper to correctly set up various integrations, such as X11, OpenGL, audio, etc, which you’d do by dumping the wrapper into your snap and then adding as a command-chain attribute, e.g

apps:
  test:
    command: bin/root
    command-chain:
      - bin/setup-sandbox.sh
  plugs: [home, x11, opengl, network, unity7]

This definitively did the job

layout:
  /usr/include:
    bind: $SNAP/usr/include

In addition, adding g++ in the list of stage-packages is mandatory in my case.

Thank you for all your suggestions, also the linked wrapper could be useful.
I was facing this problem since few weeks, so your answers have been very helpful.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.