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

argument not found on ARM linux only #1919

Closed
sab24 opened this issue Oct 6, 2020 · 21 comments
Closed

argument not found on ARM linux only #1919

sab24 opened this issue Oct 6, 2020 · 21 comments

Comments

@sab24
Copy link

sab24 commented Oct 6, 2020

The following code

#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
    return 0;
}

compiled with

clang++ fmttest.cpp -o fmttest /usr/local/lib/libfmt.a

on archlinuxarm gives

./fmttest
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found

while on MacOS it gives

./fmttest
a, b, c

Both versions are compiled from source from the latest source version.

However, compiling with format.cc seems to solve the issue:

clang++ fmttest.cpp -o fmttest -I /home/user/Downloads/fmt/include /home/user/Downloads/fmt/build/libfmt.a -v
./fmttest
./fmttest
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted (core dumped)
clang++ fmttest.cpp -o fmttest -I /home/user/Downloads/fmt/include /home/user/Downloads/fmt/src/format.cc -v
./fmttest
a, b, c
@vitaut
Copy link
Contributor

vitaut commented Oct 6, 2020

I don't have an ARM box to repro so you'll need to provide more details, e.g. the exception stack trace and exact version (or commit hash).

Also I recommend a clean rebuild from source to make sure you don't have an incompatible version of the library (which is the most likely cause).

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

git log
commit 7277035736eb991207d8f95077e607b68f4b5ebe (HEAD -> master, origin/master, origin/HEAD)
Author: francesco-st <68635116+francesco-st@users.noreply.github.com>
Date:   Mon Oct 5 15:42:02 2020 +0200

    Fix long lines in usage.md
clang++ fmttest.cpp -o fmttest -I /home/user/Downloads/fmt/include /home/user/Downloads/fmt/build/libfmt.a -v -g
lldb ./fmttest
r
bt
Process 24229 launched: '/tmp/fmttest' (arm)
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Process 24229 stopped
* thread #1, name = 'fmttest', stop reason = signal SIGABRT
    frame #0: 0x76c71aa0 libc.so.6`raise + 188
libc.so.6`raise:
->  0x76c71aa0 <+188>: ldr    r2, [pc, #0x50]           ; <+276>
    0x76c71aa4 <+192>: ldr    r3, [pc, #0x48]           ; <+272>
    0x76c71aa8 <+196>: add    r2, pc, r2
    0x76c71aac <+200>: ldr    r3, [r2, r3]
(lldb) bt
* thread #1, name = 'fmttest', stop reason = signal SIGABRT
  * frame #0: 0x76c71aa0 libc.so.6`raise + 188
    frame #1: 0x76c5ad7c libc.so.6`abort + 276
    frame #2: 0x76eb0848 libstdc++.so.6`__gnu_cxx::__verbose_terminate_handler() at vterminate.cc:95:10
    frame #3: 0x76eae0ac libstdc++.so.6`__cxxabiv1::__terminate(handler=<unavailable>)()) at eh_terminate.cc:48:15
    frame #4: 0x76eae138 libstdc++.so.6`std::terminate() at eh_terminate.cc:58:15
    frame #5: 0x76eae508 libstdc++.so.6`__cxxabiv1::__cxa_throw(obj=<unavailable>, tinfo=<unavailable>, dest=<unavailable>)(void *)) at eh_throw.cc:95:18
    frame #6: 0x00401670 fmttest`fmt::v7::detail::error_handler::on_error(char const*) (.constprop.0) + 72
    frame #7: 0x00415530 fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(char const*, char const*, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&) + 340
    frame #8: 0x004161cc fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator, fmt::v7::basic_string_view<char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >, fmt::v7::detail::locale_ref) + 1692
    frame #9: 0x0041650c fmttest`fmt::v7::detail::buffer_appender<char> fmt::v7::detail::vformat_to<char>(fmt::v7::detail::buffer<char>&, fmt::v7::basic_string_view<char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<fmt::v7::type_identity<char>::type>, fmt::v7::type_identity<char>::type> >) + 52
    frame #10: 0x00402e64 fmttest`fmt::v7::detail::vformat[abi:cxx11](fmt::v7::basic_string_view<char>, fmt::v7::format_args) + 144
    frame #11: 0x00401da4 fmttest`main [inlined] std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > fmt::v7::format<char [14], char, char, char, char>(format_str=<no value available>, args=0x7efffaa7, args=0x7efffaa6, args=0x7efffaa5) [14], char&&, char&&, char&&) at core.h:2083:10
    frame #12: 0x00401ce0 fmttest`main at fmttest.cpp:5
    frame #13: 0x76c5b154 libc.so.6`__libc_start_main + 272
    frame #14: 0x00401b40 fmttest`_start + 68

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

I can confirm it is a clean rebuild as there are no fmt files anywhere on the system

find / -name fmt
/usr/bin/fmt
find / -name core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/sound/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/cec/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/iio/st/sensors/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/async/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mma9551/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/elf/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mfd/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mfd/rpisense/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/sound/oss/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/touchscreen/cyttsp/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/touchscreen/tsc200x/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/touchscreen/cyttsp4/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/videobuf2/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/wext/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/watchdog/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/serial/sc16is7xx/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/serial/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/rmi4/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mtd/nand/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mt76/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/tcg/tis/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/net/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/usbip/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/dvb/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/rc/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/arch/has/membarrier/sync/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/target/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mmc/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/mt6397/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/wm8350/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/madera/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9062/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/mt6323/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/arizona/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/samsung/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/wm831x/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9150/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/pcf50633/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/wm8994/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/rpisense/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9063/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9055/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/can/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/net/netns/core.h
clang++ ./fmttest.cpp  -o fmttest-l fmt
./fmttest.cpp:1:10: fatal error: 'fmt/core.h' file not found
#include <fmt/core.h>
         ^~~~~~~~~~~~
1 error generated.
git clone https://github.com/fmtlib/fmt.git
cd fmt && mkdir build && cd build && cmake .. && make 
sudo make install
clang++ ./fmttest.cpp  -o fmttest -l fmt
./fmttest

terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted (core dumped)
find / -name fmt
/usr/bin/fmt
/usr/local/lib/cmake/fmt
/usr/local/include/fmt
/tmp/fmt
/tmp/fmt/build/CMakeFiles/Export/lib/cmake/fmt
/tmp/fmt/include/fmt
 find / -name core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/sound/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/cec/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/iio/st/sensors/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/async/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mma9551/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/elf/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mfd/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mfd/rpisense/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/sound/oss/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/touchscreen/cyttsp/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/touchscreen/tsc200x/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/touchscreen/cyttsp4/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/videobuf2/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/wext/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/watchdog/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/serial/sc16is7xx/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/serial/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/rmi4/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mtd/nand/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/mt76/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/tcg/tis/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/net/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/usbip/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/dvb/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/rc/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/arch/has/membarrier/sync/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/config/target/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mmc/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/mt6397/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/wm8350/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/madera/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9062/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/mt6323/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/arizona/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/samsung/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/wm831x/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9150/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/pcf50633/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/wm8994/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/rpisense/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9063/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/mfd/da9055/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/linux/can/core.h
/usr/lib/modules/5.4.65-1-ARCH/build/include/net/netns/core.h
/usr/local/include/fmt/core.h
/tmp/fmt/include/fmt/core.h

@vitaut
Copy link
Contributor

vitaut commented Oct 6, 2020

Could you build libfmt with debug information and post the stack trace for that? Otherwise there are no locations.

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

 clang++ ./fmttest.cpp -o fmttest -l fmtd -g
 lldb ./fmttest
(lldb) target create "./fmttest"
Current executable set to '/tmp/fmttest' (arm).
(lldb) r
Process 27873 launched: '/tmp/fmttest' (arm)
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Process 27873 stopped
* thread #1, name = 'fmttest', stop reason = signal SIGABRT
    frame #0: 0x76c71aa0 libc.so.6`raise + 188
libc.so.6`raise:
->  0x76c71aa0 <+188>: ldr    r2, [pc, #0x50]           ; <+276>
    0x76c71aa4 <+192>: ldr    r3, [pc, #0x48]           ; <+272>
    0x76c71aa8 <+196>: add    r2, pc, r2
    0x76c71aac <+200>: ldr    r3, [r2, r3]
(lldb) bt
* thread #1, name = 'fmttest', stop reason = signal SIGABRT
  * frame #0: 0x76c71aa0 libc.so.6`raise + 188
    frame #1: 0x76c5ad7c libc.so.6`abort + 276
    frame #2: 0x76eb0848 libstdc++.so.6`__gnu_cxx::__verbose_terminate_handler() at vterminate.cc:95:10
    frame #3: 0x76eae0ac libstdc++.so.6`__cxxabiv1::__terminate(handler=<unavailable>)()) at eh_terminate.cc:48:15
    frame #4: 0x76eae138 libstdc++.so.6`std::terminate() at eh_terminate.cc:58:15
    frame #5: 0x76eae508 libstdc++.so.6`__cxxabiv1::__cxa_throw(obj=<unavailable>, tinfo=<unavailable>, dest=<unavailable>)(void *)) at eh_throw.cc:95:18
    frame #6: 0x004036dc fmttest`fmt::v7::detail::error_handler::on_error(this=0x7efff610, message="argument not found") at format-inl.h:2736:3
    frame #7: 0x0041bbf4 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::on_error(this=0x7efff738, message="argument not found") at core.h:1539:64
    frame #8: 0x00419f48 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::format_arg fmt::v7::detail::get_arg<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>, int>(ctx=0x7efff738, id=0) at format.h:2432:25
    frame #9: 0x00415ca4 fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(char const*, char const*, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&) [inlined] fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >::on_replacement_field((null)="}, {1}, {2}", id=0, this=0x7efff728) at format.h:2930:23
    frame #10: 0x00415c8c fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(begin="}, {1}, {2}", end="", handler=0x7efff728) at format.h:2826
    frame #11: 0x0040e044 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator, fmt::v7::basic_string_view<char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >, fmt::v7::detail::locale_ref) at format.h:2850:44
    frame #12: 0x0040df9c fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(out=fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator @ 0x7efff6f4, format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> > @ 0x7efff770, loc=(locale_ = 0x00000000)) at format.h:3496
    frame #13: 0x004092c4 fmttest`fmt::v7::detail::buffer_appender<char> fmt::v7::detail::vformat_to<char>(buf=0x7efff844, format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> > @ 0x7efff7b0) at format.h:3671:24
    frame #14: 0x00403ae8 fmttest`fmt::v7::detail::vformat[abi:cxx11](format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=format_args @ 0x7efffa60) at format-inl.h:2751:46
    frame #15: 0x00402774 fmttest`main [inlined] std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > fmt::v7::format<char [14], char, char, char, char>(format_str=<no value available>, args=0x7efffab7, args=0x7efffab6, args=0x7efffab5) [14], char&&, char&&, char&&) at core.h:2083:10
    frame #16: 0x004026b0 fmttest`main at fmttest.cpp:5
    frame #17: 0x76c5b154 libc.so.6`__libc_start_main + 272
    frame #18: 0x00402510 fmttest`_start + 68

@vitaut
Copy link
Contributor

vitaut commented Oct 6, 2020

The stack trace shows that ctx.arg(0) returns an empty argument in

auto arg = ctx.arg(id);

although it's unclear why this happens since the ctx should contain 3 char arguments.

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

lldb confirms this:

(lldb) r
There is a running process, kill it and restart?: [Y/n] y
Process 27873 exited with status = 9 (0x00000009)
Process 27961 launched: '/tmp/fmttest' (arm)
Process 27961 stopped
* thread #1, name = 'fmttest', stop reason = breakpoint 1.1
    frame #0: 0x00419f04 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::format_arg fmt::v7::detail::get_arg<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>, int>(ctx=0x7efff738, id=0) at format.h:2431:21
   2428
   2429 template <typename Context, typename ID>
   2430 FMT_CONSTEXPR typename Context::format_arg get_arg(Context& ctx, ID id) {
-> 2431   auto arg = ctx.arg(id);
   2432   if (!arg) ctx.on_error("argument not found");
   2433   return arg;
   2434 }
(lldb) e ctx
(fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>) $0 = {
  out_ = {
    std::back_insert_iterator<fmt::v7::detail::buffer<char> > = {
      container = 0x7efff844
    }
  }
  args_ = {
    desc_ = 9151308842179493888
     = {
      values_ = 0x7efffaec
      args_ = 0x7efffaec
    }
  }
  loc_ = (locale_ = 0x00000000)
}
(lldb) e id
(int) $1 = 0
(lldb) e ctx.arg(id)
(fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::format_arg) $2 = {
  value_ = {
     = {
      int_value = 0
      uint_value = 0
      long_long_value = 0
      ulong_long_value = 0
      int128_value = {}
      uint128_value = {}
      bool_value = false
      char_value = '\0'
      float_value = 0
      double_value = 0
      long_double_value = 0
      pointer = 0x00000000
      string = (data = <no value available>, size = 0)
      custom = {
        value = 0x00000000
        format = 0x00000000
      }
      named_args = {
        data = 0x00000000
        size = 0
      }
    }
  }
  type_ = none_type
}

@mwinterb
Copy link
Contributor

mwinterb commented Oct 6, 2020

This question is probably just noise, but does this happen with ints, too? Or just chars?

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

With numbers the result is the same and stack trace shows the same path.

cat ./fmttest.cpp
#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << fmt::format("{0}, {1}, {2}", 1, 2, 42);
    return 0;
}
clang++ ./fmttest.cpp -o fmttest -l fmtd -g
lldb ./fmttest
(lldb) r
Process 28025 launched: '/tmp/fmttest' (arm)
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Process 28025 stopped
* thread #1, name = 'fmttest', stop reason = signal SIGABRT
    frame #0: 0x76c71aa0 libc.so.6`raise + 188
libc.so.6`raise:
->  0x76c71aa0 <+188>: ldr    r2, [pc, #0x50]           ; <+276>
    0x76c71aa4 <+192>: ldr    r3, [pc, #0x48]           ; <+272>
    0x76c71aa8 <+196>: add    r2, pc, r2
    0x76c71aac <+200>: ldr    r3, [r2, r3]
(lldb) bt
* thread #1, name = 'fmttest', stop reason = signal SIGABRT
  * frame #0: 0x76c71aa0 libc.so.6`raise + 188
    frame #1: 0x76c5ad7c libc.so.6`abort + 276
    frame #2: 0x76eb0848 libstdc++.so.6`__gnu_cxx::__verbose_terminate_handler() at vterminate.cc:95:10
    frame #3: 0x76eae0ac libstdc++.so.6`__cxxabiv1::__terminate(handler=<unavailable>)()) at eh_terminate.cc:48:15
    frame #4: 0x76eae138 libstdc++.so.6`std::terminate() at eh_terminate.cc:58:15
    frame #5: 0x76eae508 libstdc++.so.6`__cxxabiv1::__cxa_throw(obj=<unavailable>, tinfo=<unavailable>, dest=<unavailable>)(void *)) at eh_throw.cc:95:18
    frame #6: 0x004036dc fmttest`fmt::v7::detail::error_handler::on_error(this=0x7efff608, message="argument not found") at format-inl.h:2736:3
    frame #7: 0x0041baf4 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::on_error(this=0x7efff730, message="argument not found") at core.h:1539:64
    frame #8: 0x00419e48 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::format_arg fmt::v7::detail::get_arg<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>, int>(ctx=0x7efff730, id=0) at format.h:2432:25
    frame #9: 0x00415bf0 fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(char const*, char const*, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&) [inlined] fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >::on_replacement_field((null)="}, {1}, {2}", id=0, this=0x7efff720) at format.h:2930:23
    frame #10: 0x00415bd8 fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(begin="}, {1}, {2}", end="", handler=0x7efff720) at format.h:2826
    frame #11: 0x0040e044 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator, fmt::v7::basic_string_view<char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >, fmt::v7::detail::locale_ref) at format.h:2850:44
    frame #12: 0x0040df9c fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(out=fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator @ 0x7efff6ec, format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> > @ 0x7efff768, loc=(locale_ = 0x00000000)) at format.h:3496
    frame #13: 0x004092c4 fmttest`fmt::v7::detail::buffer_appender<char> fmt::v7::detail::vformat_to<char>(buf=0x7efff83c, format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> > @ 0x7efff7a8) at format.h:3671:24
    frame #14: 0x00403ae8 fmttest`fmt::v7::detail::vformat[abi:cxx11](format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=format_args @ 0x7efffa58) at format-inl.h:2751:46
    frame #15: 0x00402774 fmttest`main [inlined] std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > fmt::v7::format<char [14], int, int, int, char>(format_str=<no value available>, args=0x7efffab4, args=0x7efffab0, args=0x7efffaac) [14], int&&, int&&, int&&) at core.h:2083:10
    frame #16: 0x004026b0 fmttest`main at fmttest.cpp:5
    frame #17: 0x76c5b154 libc.so.6`__libc_start_main + 272
    frame #18: 0x00402510 fmttest`_start + 68

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

This seems to be LLVM specific. The library has been compiled with GCC

cat ./fmttest.cpp
#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << fmt::format("{0}, {1}, {2}", 1, 2, 42);
    return 0;
}
g++ ./fmttest.cpp -o fmttest -l fmtd -g
./fmttest
1, 2, 42
clang++ ./fmttest.cpp -o fmttest -l fmtd -g
./fmttest
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted (core dumped)

@sab24
Copy link
Author

sab24 commented Oct 6, 2020

compiling fmt with clang

CC=clang CXX=clang++ cmake .. -DCMAKE_BUILD_TYPE=Debug

gives

clang++ fmttest.cpp -o fmttest -l fmtd -g
./fmttest
1, 2, 42
g++ fmttest.cpp -o fmttest -l fmtd -g
./fmttest
Segmentation fault (core dumped)
lldb ./fmttest
(lldb) target create "./fmttest"
Current executable set to '/tmp/fmttest' (arm).
(lldb) r
Process 28591 launched: '/tmp/fmttest' (arm)
Process 28591 stopped
* thread #1, name = 'fmttest', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
    frame #0: 0x00405020 fmttest`fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >::get(this=0x7efff5f0, id=0) const at core.h:1922:16
   1919     if (id >= detail::max_packed_args) return arg;
   1920     arg.type_ = type(id);
   1921     if (arg.type_ == detail::type::none_type) return arg;
-> 1922     arg.value_ = values_[id];
   1923     return arg;
   1924   }
   1925
(lldb) bt
* thread #1, name = 'fmttest', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
  * frame #0: 0x00405020 fmttest`fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >::get(this=0x7efff5f0, id=0) const at core.h:1922:16
    frame #1: 0x00417c18 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::arg(this=0x7efff5e8, id=0) const at core.h:1533:47
    frame #2: 0x00417b4c fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::format_arg fmt::v7::detail::get_arg<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>, int>(ctx=0x7efff5e8, id=0) at format.h:2431:18
    frame #3: 0x00416b18 fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(char const*, char const*, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&) [inlined] fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >::on_replacement_field(this=0x7efff5d8, id=0, (null)="}, {1}, {2}") at format.h:2930:16
    frame #4: 0x00416af4 fmttest`char const* fmt::v7::detail::parse_replacement_field<char, fmt::v7::detail::format_handler<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >&>(begin="}, {1}, {2}", end="", handler=0x7efff5d8) at format.h:2826
    frame #5: 0x00405b68 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator, fmt::v7::basic_string_view<char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >, fmt::v7::detail::locale_ref) at format.h:2850:21
    frame #6: 0x00405ac0 fmttest`fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char>::iterator fmt::v7::vformat_to<fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, char, fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> >(out=fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>::iterator @ 0x7efff59c, format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> > @ 0x7efff638, loc=(locale_ = 0x00000000)) at format.h:3496
    frame #7: 0x00405120 fmttest`fmt::v7::detail::buffer_appender<char> fmt::v7::detail::vformat_to<char>(buf=0x7efff864, format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<char>, char> > @ 0x7efff6b8) at format.h:3671:10
    frame #8: 0x004041f0 fmttest`fmt::v7::detail::vformat[abi:cxx11](format_str=(data_ = "{0}, {1}, {2}", size_ = 13), args=format_args @ 0x7efff850) at format-inl.h:2751:3
    frame #9: 0x00402a5c fmttest`main [inlined] std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > fmt::v7::format<char [14], int, int, int, char>((null)=<unavailable>, (null)=<unavailable>, (null)=<unavailable>, format_str=<unavailable>) [14], int&&, int&&, int&&) at core.h:2083:59
    frame #10: 0x004029c0 fmttest`main at fmttest.cpp:5
    frame #11: 0x76c5b154 libc.so.6`__libc_start_main + 272
    frame #12: 0x0040283c fmttest`_start + 68

@vitaut
Copy link
Contributor

vitaut commented Oct 7, 2020

The value of ctx.args_.desc_ is incorrect:

desc_ = 9151308842179493888

It should be 2184 (0x888) and the current value resembles a pointer (0x7efffae800000000). It looks like there is some incompatibility between clang and gcc.

@sab24
Copy link
Author

sab24 commented Oct 7, 2020

on LLVM discord they said it is similar to itanium-cxx-abi/cxx-abi#66

I just confirmed that also on other ARM build this problem occurs. With Fedora it is possible to run arm relatively easy:

https://fedoraproject.org/wiki/QA:Testcase_Virt_ARM_on_x86

resizing that image to create some space, install llvm, clang git and cmake on it and run it.

g++ fmttest.cpp -o fmttest -I ~/fmt/include -L ~/fmt/build -lfmt
clang++ fmttest.cpp -o fmttestclang -I ~/fmt/include -L ~/fmt/build -lfmt
./fmttest
a, b, c[root@localhost fmttest]#./fmttestclang
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted (core dumped)

It's strange this problem does not occur on x86 Linux

@vitaut
Copy link
Contributor

vitaut commented Oct 17, 2020

Interestingly, it doesn't happen on all ARM systems (or could depend on compiler version). For example, on my Raspberry PI gcc and clang generate compatible code:

pi@raspberrypi:~/fmt $ g++ --version
g++ (Raspbian 4.9.2-10+deb8u2) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

pi@raspberrypi:~/fmt $ clang++ --version
Raspbian clang version 3.5.0-10+rpi1 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: arm-unknown-linux-gnueabihf
Thread model: posix
pi@raspberrypi:~/fmt $ cat test.cc
#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
    return 0;
}
pi@raspberrypi:~/fmt $ clang++ test.cc -std=c++11 libfmt.a  -I include
pi@raspberrypi:~/fmt $ ./a.out
a, b, cpi@raspberrypi:~
pi@raspberrypi:~/fmt $ g++ test.cc -std=c++11 libfmt.a  -I include
pi@raspberrypi:~/fmt $ ./a.out
a, b, c

@sab24
Copy link
Author

sab24 commented Oct 17, 2020

These are prehistorical versions of llvm and gcc, I used gcc 10 and llvm 11. I ran archlinux on rpi4 to have latest versions of these compilers

@vitaut
Copy link
Contributor

vitaut commented Oct 31, 2020

Managed to repro the issue on Raspberry Pi 4 with clang version 7.0.1-8+rpi3+deb10u2 (tags/RELEASE_701/final) and gcc (Raspbian 8.3.0-6+rpi1) 8.3.0 and implemented a workaround in e50ced8.

The workaround is enabled by defining the FMT_ARM_ABI_COMPATIBILITY macro:

git clone https://github.com/fmtlib/fmt.git
cd fmt
cmake -DCMAKE_CXX_FLAGS=-DFMT_ARM_ABI_COMPATIBILITY .
make fmt
cat >> test.cc << EOF
#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
    return 0;
}
EOF
clang++ -DFMT_ARM_ABI_COMPATIBILITY test.cc -Iinclude -lfmt -L.
./a.out

Output:

a, b, c

The workaround will become the default in the next major release since it is ABI breaking.

Thanks for reporting.

@vitaut vitaut closed this as completed Oct 31, 2020
@sab24
Copy link
Author

sab24 commented Oct 31, 2020

Hi vitaut,

thanks for the work done. I'm on e50ced8, which is

Date:   Sat Oct 31 07:51:39 2020 -0700

    Add a macro to workaround clang/gcc ABI incompatibility on ARM

and I compiled by using cmake .. with gcc 10.2.0, installed it and verified it overwrote /usr/local/lib/ilbfmt.a to the newest version.

$ cat ./test.cpp
#include <fmt/core.h>
#include <iostream>

int main() {
    std::cout << fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
    return 0;
}
$ clang++ --version
clang version 10.0.1
Target: armv7l-unknown-linux-gnueabihf
Thread model: posix
InstalledDir: /usr/bin
$ clang++ ./test.cpp -o test /usr/local/lib/libfmt.a
$ ./test
terminate called after throwing an instance of 'fmt::v7::format_error'
  what():  argument not found
Aborted (core dumped)

I think the LLVM and GCC versions are too old, they are from 2018 and beginning of 2019 respectively. Newer versions still fail.

The raspberry pi 4 is powerful enough to compile llvm from source to checkout head, but other than that with Debian I have no idea how to get newer versions on your system. Problems with old versions of software were my main reason never to use Debian again.

@sab24
Copy link
Author

sab24 commented Oct 31, 2020

Ah, sorry I missed the CMake flag, will recompile it now again.

@vitaut
Copy link
Contributor

vitaut commented Oct 31, 2020

Not just CMake but compiler too. You are missing the flag in both places.

@sab24
Copy link
Author

sab24 commented Oct 31, 2020

Yes, now it works, thanks for the fix! Next major release will be fmt 8, that will be next year right? I see a lot of activity, do you work on this project fulltime? Great work btw.

@vitaut
Copy link
Contributor

vitaut commented Oct 31, 2020

Thanks for verifying the fix.

Next major release will be fmt 8, that will be next year right?

Yes.

I see a lot of activity, do you work on this project fulltime?

No, only part time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants