cling seems to segfault easily
Apteryks opened this issue · comments
Describe the bug
While experimenting with cling I found that I can have it segfault on demand with the recipe below.
Expected behavior
cling should not segfault itself.
To Reproduce
Steps to reproduce the behavior:
- launch cling with
cling --std=c++17
. - input the following code:
#include <filesystem>
auto p = std::filesystem::path("/etc/pulse/client.conf");
auto cp = std::filesystem::canonical(p);
cp
The last line (an attempt to inspect cp), triggers a segfault for me (exit status 139 with error message "Segmentation fault").
Setup
- Cling version: 0.9-1.d78d1a0
- Operating system: Guix System
- How you obtained Cling: installed from Guix (commit ff14bc60e56fb0c6636da1da9a850b7b04abb367).
This is not a Cling issue per se. It's to do with std::filesystem::path
usage and a mixup between the headers used and what's linked to your binary. Lots more info here:
- https://stackoverflow.com/questions/63902528/program-crashes-when-filesystempath-is-destroyed
- https://stackoverflow.com/questions/56615841/passing-stdfilesystempath-to-a-function-segfaults
I've seen the same thing. Perhaps Cling could make this easier to avoid.
The above links were very insightful, but I'm not using GCC 8 (I'm using a mixture of GCC 10.3.0 for the build and GCC 12.2.0 in my user profile (Guix).
The Guix package of cling reads as:
(define-public cling
;; The tagged v0.9 release doesn't build, so use the latest commit.
(let ((commit "d78d1a03fedfd2bf6d2b6ff295aca576d98940df")
(revision "1")
(version* "0.9"))
(package
(name "cling")
(version (git-version version* revision commit))
(source (origin
(method git-fetch)
(uri (git-reference
(url "http://root.cern/git/cling.git")
(commit commit)))
(file-name (git-file-name name version))
(sha256
(base32
"0lsbxv21b4qw11xkw9iipdpca64jjwwqxm0qf5v2cgdlibf8m8n9"))
;; Patch submitted upstream here:
;; https://github.com/root-project/cling/pull/433.
(patches (search-patches "cling-use-shared-library.patch"))))
(build-system cmake-build-system)
(arguments
(list
#:build-type "Release" ;keep the build as lean as possible
#:tests? #f ;FIXME: 78 tests fail (out of ~200)
#:test-target "check-cling"
#:configure-flags
#~(list (string-append "-DCLING_CXX_PATH="
(search-input-file %build-inputs "bin/g++"))
;; XXX: The AddLLVM.cmake module expects LLVM_EXTERNAL_LIT to
;; be a Python script, not a shell executable.
(string-append "-DLLVM_EXTERNAL_LIT="
(search-input-file %build-inputs "bin/.lit-real")))
#:phases
#~(modify-phases %standard-phases
(add-after 'unpack 'set-version
(lambda _
(make-file-writable "VERSION")
(call-with-output-file "VERSION"
(lambda (port)
(format port "~a~%" #$version)))))
(add-after 'unpack 'patch-paths
(lambda* (#:key inputs #:allow-other-keys)
(substitute* "lib/Interpreter/CIFactory.cpp"
(("\bsed\b")
(which "sed"))
;; This ensures that the default C++ library used by Cling is
;; that of the compiler that was used to build it, rather
;; than that of whatever g++ happens to be on PATH.
(("ReadCompilerIncludePaths\\(CLING_CXX_RLTV")
(format #f "ReadCompilerIncludePaths(~s"
(search-input-file inputs "bin/g++")))
;; Cling uses libclang's CompilerInvocation::GetResourcesPath
;; to resolve Clang's library prefix, but this fails on Guix
;; because it is relative to the output of cling rather than
;; clang (see:
;; https://github.com/root-project/cling/issues/434). Fully
;; shortcut the logic in this method to return the correct
;; static location.
(("static std::string getResourceDir.*" all)
(string-append all
" return std::string(\""
#$(this-package-input "clang-cling")
"/lib/clang/" #$(package-version clang-cling)
"\");")))
;; Check for the 'lit' command for the tests, not 'lit.py'
;; (see: https://github.com/root-project/cling/issues/432).
(substitute* "CMakeLists.txt"
(("lit.py")
"lit"))))
(add-after 'unpack 'adjust-lit.cfg
;; See: https://github.com/root-project/cling/issues/435.
(lambda _
(substitute* "test/lit.cfg"
(("config.llvm_tools_dir \\+ '")
"config.cling_obj_root + '/bin"))))
(add-after 'install 'delete-static-libraries
;; This reduces the size from 17 MiB to 5.4 MiB.
(lambda _
(for-each delete-file (find-files #$output "\\.a$")))))))
(native-inputs
(list python python-lit))
(inputs
(list clang-cling llvm-cling))
(home-page "https://root.cern/cling/")
(synopsis "Interactive C++ interpreter")
(description "Cling is an interactive C++17 standard compliant
interpreter, built on top of LLVM and Clang. Cling can be used as a
read-eval-print loop (REPL) to assist with rapid application development.
Here's how to print @samp{\"Hello World!\"} using @command{cling}:
@example
cling '#include <stdio.h>' 'printf(\"Hello World!\\n\");'
@end example")
(license license:lgpl2.1+))))
Note the patching of the ReadCompilerIncludePaths(CLING_CXX_RLTV
to use the g++ from the build environment rather than from the user's PATH. I'll try commenting this out to see if it improves things.
OK, I've done the experiment, and I now get:
$ /gnu/store/wkgf0f1605w5j4k39bma9w8y17j8nycb-cling-0.9-1.d78d1a0/bin/cling
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
[cling]$ #include <filesystem>
[cling]$ auto p = std::filesystem::path("/etc/pulse/client.conf");
input_line_4:2:16: error: no member named 'filesystem' in namespace 'std'
auto p = std::filesystem::path("/etc/pulse/client.conf");
~~~~~^
OK, I've done the experiment, and I now get:
$ /gnu/store/wkgf0f1605w5j4k39bma9w8y17j8nycb-cling-0.9-1.d78d1a0/bin/cling ****************** CLING ****************** * Type C++ code and press enter to run it * * Type .q to exit * ******************************************* [cling]$ #include <filesystem> [cling]$ auto p = std::filesystem::path("/etc/pulse/client.conf"); input_line_4:2:16: error: no member named 'filesystem' in namespace 'std' auto p = std::filesystem::path("/etc/pulse/client.conf"); ~~~~~^
std::filesystem
was added in c++17 IIRC. cling defaults to c++11 IIRC. To use std::filesystem
with cling, you need to start it as follows:
cling -std=c++17
I tried to run cling in a container; if I don't include a GCC toolchain with its headers it doesn't find the linux/errno.h header:
$ guix shell --container cling -- cling -std=c++17
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
[cling]$
[cling]$ #include <filesystem>
In file included from input_line_3:1:
In file included from /gnu/store/5lqhcv91ijy82p92ac6g5xw48l0lwwz4-gcc-11.3.0/include/c++/filesystem:44:
In file included from /gnu/store/5lqhcv91ijy82p92ac6g5xw48l0lwwz4-gcc-11.3.0/include/c++/bits/fs_fwd.h:35:
In file included from /gnu/store/5lqhcv91ijy82p92ac6g5xw48l0lwwz4-gcc-11.3.0/include/c++/system_error:39:
In file included from /gnu/store/5lqhcv91ijy82p92ac6g5xw48l0lwwz4-gcc-11.3.0/include/c++/x86_64-unknown-linux-gnu/bits/error_constants.h:34:
In file included from /gnu/store/5lqhcv91ijy82p92ac6g5xw48l0lwwz4-gcc-11.3.0/include/c++/cerrno:42:
In file included from /gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/include/errno.h:28:
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/include/bits/errno.h:26:11: fatal error: 'linux/errno.h' file not found
# include <linux/errno.h>
^~~~~~~~~~~~~~~
If I do, I still get a crash:
$ guix shell --container cling gcc-toolchain@11 -- cling -std=c++17
[...]
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
[cling]$ #include <filesystem>
[cling]$ std::filesystem::path("/etc/pulse/client.conf");
free(): invalid pointer
/gnu/store/havpcz2bgi5fd0fj52r7pgb4f73z465x-llvm-cling-9.0.1/lib/libLLVM-9.so(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x3b)[0x7f94506ce4bb]
/gnu/store/havpcz2bgi5fd0fj52r7pgb4f73z465x-llvm-cling-9.0.1/lib/libLLVM-9.so(_ZN4llvm3sys17RunSignalHandlersEv+0x34)[0x7f94506cc514]
/gnu/store/havpcz2bgi5fd0fj52r7pgb4f73z465x-llvm-cling-9.0.1/lib/libLLVM-9.so(+0x70f642)[0x7f94506cc642]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x3d2a0)[0x7f944faf22a0]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x86fec)[0x7f944fb3bfec]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(raise+0x12)[0x7f944faf2202]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(abort+0xc1)[0x7f944fadd45b]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(__libc_fatal+0x0)[0x7f944fb30990]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x904ba)[0x7f944fb454ba]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x91fcc)[0x7f944fb46fcc]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(free+0x6f)[0x7f944fb49b3f]
/gnu/store/930nwsiysdvy2x5zv1sf6v7ym75z8ayk-gcc-11.3.0-lib/lib/libstdc++.so.6(_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE+0x4a)[0x7f944ff1e44a]
[0x7f944f995482]
[0x7f944f9953fc]
[0x7f944f99516c]
[0x7f944f99513c]
[0x7f944f99534d]
[0x7f944f99530c]
[0x7f944f99503b]
cling(_ZNK5cling19IncrementalExecutor14executeWrapperEN4llvm9StringRefEPNS_5ValueE+0x30c)[0x51057c]
Stack dump:
0. Program arguments: cling -std=c++17
maxim@hurd ~$ guix shell --container cling gcc-toolchain@11 -- cling -std=c++17
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
[cling]$ std::filesystem::path("/");
input_line_3:2:7: error: no member named 'filesystem' in namespace 'std'
std::filesystem::path("/");
~~~~~^
[cling]$ #include <filesystem>
^[[A[cling]$ std::filesystem::path("/");
free(): invalid pointer
/gnu/store/havpcz2bgi5fd0fj52r7pgb4f73z465x-llvm-cling-9.0.1/lib/libLLVM-9.so(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x3b)[0x7fe53f9064bb]
/gnu/store/havpcz2bgi5fd0fj52r7pgb4f73z465x-llvm-cling-9.0.1/lib/libLLVM-9.so(_ZN4llvm3sys17RunSignalHandlersEv+0x34)[0x7fe53f904514]
/gnu/store/havpcz2bgi5fd0fj52r7pgb4f73z465x-llvm-cling-9.0.1/lib/libLLVM-9.so(+0x70f642)[0x7fe53f904642]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x3d2a0)[0x7fe53ed2a2a0]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x86fec)[0x7fe53ed73fec]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(raise+0x12)[0x7fe53ed2a202]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(abort+0xc1)[0x7fe53ed1545b]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(__libc_fatal+0x0)[0x7fe53ed68990]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x904ba)[0x7fe53ed7d4ba]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(+0x91fcc)[0x7fe53ed7efcc]
/gnu/store/gsjczqir1wbz8p770zndrpw4rnppmxi3-glibc-2.35/lib/libc.so.6(free+0x6f)[0x7fe53ed81b3f]
/gnu/store/930nwsiysdvy2x5zv1sf6v7ym75z8ayk-gcc-11.3.0-lib/lib/libstdc++.so.6(_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE+0x4a)[0x7fe53f15644a]
[0x7fe53ebcd482]
[0x7fe53ebcd3fc]
[0x7fe53ebcd16c]
[0x7fe53ebcd13c]
[0x7fe53ebcd34d]
[0x7fe53ebcd30c]
[0x7fe53ebcd03b]
cling(_ZNK5cling19IncrementalExecutor14executeWrapperEN4llvm9StringRefEPNS_5ValueE+0x30c)[0x51057c]
Stack dump:
0. Program arguments: cling -std=c++17
The version of GCC used at build time (GCC 11) is the same provided in the container; but it seems there's a problem between LLVM 9 used by Cling and GCC 11 in my environment?
I retried with latest master, and I get:
(std::filesystem::path &) /etc/pulse/client.conf
Please retry on your side with that version and reopen if needed, thanks!
Seems to work fine as of cling v1.0. Thanks for checking!