Tests fails when compiling with LTO
Closed this issue · 10 comments
Not critical, but thought it would be good to keep a record of it.
gcc: 14.2.1
cpptrace: 0.7.2
gtest: 1.14.0
Full log:
Running main() from /var/tmp/portage/dev-cpp/gtest-1.14.0-r1/work/googletest-1.14.0/googletest/src/gtest_main.cc
[==========] Running 18 tests from 6 test suites.
[----------] Global test environment set-up.
[----------] 1 test from TracedException
[ RUN ] TracedException.Basic
[ OK ] TracedException.Basic (30 ms)
[----------] 1 test from TracedException (30 ms total)
[----------] 3 tests from FromCurrentZ
[ RUN ] FromCurrentZ.Basic
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:56: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 37
line_numbers[j]
Which is: 20
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:57: Failure
Value of: trace.frames[i].symbol
Expected: has substring "stacktrace_from_current_z_3"
Actual: "FromCurrentZ_Basic_Test::TestBody()"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:62: Failure
Value of: trace.frames[i].filename
Expected: ends with "from_current_z.cpp"
Actual: "/usr/lib64/libgtest.so.1.14.0"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:63: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 4294967295
line_numbers[j]
Which is: 25
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:64: Failure
Value of: trace.frames[i].symbol
Expected: has substring "stacktrace_from_current_z_2"
Actual: ""
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:69: Failure
Value of: trace.frames[i].filename
Expected: ends with "from_current_z.cpp"
Actual: "/usr/lib64/libgtest.so.1.14.0"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:70: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 4294967295
line_numbers[j]
Which is: 30
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:71: Failure
Value of: trace.frames[i].symbol
Expected: has substring "stacktrace_from_current_z_1"
Actual: ""
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:76: Failure
Value of: trace.frames[i].filename
Expected: ends with "from_current_z.cpp"
Actual: "/usr/lib64/libgtest.so.1.14.0"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:77: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 4294967295
line_numbers[j]
Which is: 37
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/from_current_z.cpp:78: Failure
Value of: trace.frames[i].symbol
Expected: has substring "FromCurrentZ_Basic_Test::TestBody"
Actual: ""
[ FAILED ] FromCurrentZ.Basic (3 ms)
[ RUN ] FromCurrentZ.CorrectHandler
[ OK ] FromCurrentZ.CorrectHandler (0 ms)
[ RUN ] FromCurrentZ.RawTrace
[ OK ] FromCurrentZ.RawTrace (0 ms)
[----------] 3 tests from FromCurrentZ (3 ms total)
[----------] 3 tests from FromCurrent
[ RUN ] FromCurrent.Basic
[ OK ] FromCurrent.Basic (0 ms)
[ RUN ] FromCurrent.CorrectHandler
[ OK ] FromCurrent.CorrectHandler (0 ms)
[ RUN ] FromCurrent.RawTrace
[ OK ] FromCurrent.RawTrace (0 ms)
[----------] 3 tests from FromCurrent (0 ms total)
[----------] 5 tests from Stacktrace
[ RUN ] Stacktrace.Empty
[ OK ] Stacktrace.Empty (0 ms)
[ RUN ] Stacktrace.Basic
[ OK ] Stacktrace.Basic (8 ms)
[ RUN ] Stacktrace.MultipleFrames
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:57: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 77
line_numbers[i]
Which is: 72
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:58: Failure
Value of: trace.frames[i].symbol
Expected: has substring "stacktrace_multi_2"
Actual: "stacktrace_multi_1(std::vector<int, std::allocator<int> >&)"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:61: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 83
line_numbers[i]
Which is: 77
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:62: Failure
Value of: trace.frames[i].symbol
Expected: has substring "stacktrace_multi_1"
Actual: "Stacktrace_MultipleFrames_Test::TestBody()"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:64: Failure
Value of: trace.frames[i].filename
Expected: ends with "stacktrace.cpp"
Actual: "/usr/lib64/libgtest.so.1.14.0"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:65: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 4294967295
line_numbers[i]
Which is: 83
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/stacktrace.cpp:66: Failure
Value of: trace.frames[i].symbol
Expected: has substring "Stacktrace_MultipleFrames_Test::TestBody"
Actual: ""
[ FAILED ] Stacktrace.MultipleFrames (0 ms)
[ RUN ] Stacktrace.RawTraceResolution
[ OK ] Stacktrace.RawTraceResolution (0 ms)
[ RUN ] Stacktrace.InlineResolution
[ OK ] Stacktrace.InlineResolution (0 ms)
[----------] 5 tests from Stacktrace (8 ms total)
[----------] 4 tests from ObjectTrace
[ RUN ] ObjectTrace.Empty
[ OK ] ObjectTrace.Empty (0 ms)
[ RUN ] ObjectTrace.Basic
[ OK ] ObjectTrace.Basic (0 ms)
[ RUN ] ObjectTrace.BasicResolution
[ OK ] ObjectTrace.BasicResolution (0 ms)
[ RUN ] ObjectTrace.Resolution
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:79: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 99
line_numbers[i]
Which is: 94
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:80: Failure
Value of: trace.frames[i].symbol
Expected: has substring "object_resolve_2"
Actual: "object_resolve_1(std::vector<int, std::allocator<int> >&)"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:83: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 105
line_numbers[i]
Which is: 99
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:84: Failure
Value of: trace.frames[i].symbol
Expected: has substring "object_resolve_1"
Actual: "ObjectTrace_Resolution_Test::TestBody()"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:86: Failure
Value of: trace.frames[i].filename
Expected: ends with "object_trace.cpp"
Actual: "/usr/lib64/libgtest.so.1.14.0"
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:87: Failure
Expected equality of these values:
trace.frames[i].line.value()
Which is: 4294967295
line_numbers[i]
Which is: 105
/var/tmp/portage/dev-cpp/cpptrace-0.7.2/work/cpptrace-0.7.2/test/unit/object_trace.cpp:88: Failure
Value of: trace.frames[i].symbol
Expected: has substring "ObjectTrace_Resolution_Test::TestBody"
Actual: ""
[ FAILED ] ObjectTrace.Resolution (0 ms)
[----------] 4 tests from ObjectTrace (0 ms total)
[----------] 2 tests from RawTrace
[ RUN ] RawTrace.Basic
[ OK ] RawTrace.Basic (0 ms)
[ RUN ] RawTrace.MultipleCalls
[ OK ] RawTrace.MultipleCalls (0 ms)
[----------] 2 tests from RawTrace (0 ms total)
[----------] Global test environment tear-down
[==========] 18 tests from 6 test suites ran. (42 ms total)
[ PASSED ] 15 tests.
[ FAILED ] 3 tests, listed below:
[ FAILED ] FromCurrentZ.Basic
[ FAILED ] Stacktrace.MultipleFrames
[ FAILED ] ObjectTrace.Resolution
3 FAILED TESTS
Thanks for opening this, definitely feels worth investigating.
I tried throwing set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
in the cmake and building with cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DCPPTRACE_BUILD_TESTING=On -DBUILD_SHARED_LIBS=Off && cmake --build build
but I wasn't able to reproduce the unit tests failing. More info would be helpful.
I used the next commands
export CFLAGS=-flto=auto
export CXXFLAGS=-flto=auto
export LDFLAGS=-flto=auto
mkdir build && cd build && cmake -DCPPTRACE_BUILD_TESTING=On -DBUILD_SHARED_LIBS=Off ..
Thanks, I gave that a try and saw failures with FromCurrentZ.Basic
but not any of the other failures. I'll take a look and test on some other platforms too.
Pushed a fix for why FromCurrentZ.Basic
was failing for me locally
Great! I don't know why the other tests fails only for me though. May be related with the GCC version? Which version do you use?
Yeah it could very well be that gcc 14 is doing something new with LTO. I would have to check what version I used but definitely older. I’ll give it a try with 14 when I am able. What platform are you on btw? And do you know what linker?
Gentoo. I'm using the default GCC linker, ld.bfd (GNU ld (Gentoo 2.43 p2) 2.43.1)
I reproduced with
export CFLAGS=-flto=auto
export CXXFLAGS=-flto=auto
export LDFLAGS=-flto=auto
mkdir build && cd build && cmake && cmake .. -DCPPTRACE_BUILD_TESTING=On -DBUILD_SHARED_LIBS=Off -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER=gcc-14
make -j && ./unittest
Looking into ObjectTrace.Resolution:
The trace generated by the test is
Stack trace (most recent call first):
#0 0x0000000000000000 in object_resolve_3(std::vector<int, std::allocator<int> >&) at /mnt/c/Users/rifkin/home/projects/cpptrace/test/unit/object_trace.cpp:56:43
#1 0x0000000000000000 in object_resolve_1(std::vector<int, std::allocator<int> >&) at /mnt/c/Users/rifkin/home/projects/cpptrace/test/unit/object_trace.cpp:105:28
#2 0x0000000000000000 in ObjectTrace_Resolution_Test::TestBody() at /mnt/c/Users/rifkin/home/projects/cpptrace/test/unit/object_trace.cpp:111:21
#3 0x0000000000000000 at /mnt/c/Users/rifkin/home/projects/cpptrace/build/unittest
The frame for object_resolve_2
is missing. This frame is also missing in gdb so I don't think it's a library bug.
Looking at objdump:
0000000000024650 <ObjectTrace_Resolution_Test::TestBody()>:
...
2469f: e8 3c fe ff ff call 244e0 <object_resolve_1(std::vector<int, std::allocator<int> >&)>
00000000000244e0 <object_resolve_1(std::vector<int, std::allocator<int> >&)>:
...
24546: e8 f5 b0 0a 00 call cf640 <object_resolve_2(std::vector<int, std::allocator<int> >&) [clone .isra.0]>
00000000000cf640 <object_resolve_2(std::vector<int, std::allocator<int> >&) [clone .isra.0]>:
...
cf6b8: e9 63 e6 ff ff jmp cdd20 <object_resolve_3(std::vector<int, std::allocator<int> >&) [clone .isra.0]>
I think it's just an issue of the call being TCO'd by LTO, despite my effort to prevent that from happening
0.7.3 is released