Skip to content

Bugfix: uninitialized static inline std::string

Wiebe van Breukelen requested to merge fix-uninitialized-string into master

While using pmt together with ccglib, I noticed an issue with the following code. Despite having an NVIDIA device available and pmt being built with NVIDIA and NVML support, the first statement results in an error:

std::unique_ptr<pmt::PMT> sensor = pmt::Create("nvidia", device_id);
// Reports error -> "Invalid or unavailable platform specified: nvidia"

std::unique_ptr<pmt::PMT> sensor = pmt::nvidia::NVIDIA::Create();
// OK

Further investigation revealed that the error originates from a string comparison in the Create method (file: common/PMT.cpp) that always fails:

// ...
if (name == nvidia::NVIDIA::name) {
// ...

The root cause is that the nvidia::NVIDIA::name constant, defined as a static inline std::string, is never initialized. As a result, the string comparison fails. The following GDB output illustrates this:


3581        _GLIBCXX20_CONSTEXPR
3582        inline
3583        typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
3584        operator==(const basic_string<_CharT>& __lhs,
3585                   const basic_string<_CharT>& __rhs) _GLIBCXX_NOEXCEPT
3586        { return (__lhs.size() == __rhs.size()
3587                  && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
3588                                                        __lhs.size())); }
3589
3590      /**
(gdb) display __lhs
3: __lhs = (const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > &) @0x7ffffffec140: {
  static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<std::__new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x7ffffffec150 "nvidia"}, _M_string_length = 6, {_M_local_buf = "nvidia\000\000\000\000\000\000\000\000\000", 
    _M_allocated_capacity = 107105284093550}}
(gdb) display __rhs
4: __rhs = (const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > &) @0x75a300: {static npos = 18446744073709551615, 
  _M_dataplus = {<std::allocator<char>> = {<std::__new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x0}, _M_string_length = 0, {
    _M_local_buf = '\000' <repeats 15 times>, _M_allocated_capacity = 0}}
(gdb)

Although defining a std::string as static inline is valid starting from C++17 (reference), the CUDA compiler seems not to fully adhere to this standard. To prevent similar issues in the future, I suggest using constexpr static inline std::string_view instead, as included in this MR. This potentially (depending on compiler optimization) has the benefit of saving some heap allocations as well.

Merge request reports

Loading