Bugfix: uninitialized static inline std::string
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.