abseil / abseil-cpp

Abseil Common Libraries (C++)

Home Page:https://abseil.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

absl::StrCat(nullptr) segfaults instead of producing an empty string with C++17

skye opened this issue · comments

Describe the bug

absl::StrCat(nullptr) segfaults when compiled with clang and C++17. I expect it to return an empty string.

This is similar to #64.

Steps to reproduce the bug

Any program calling absl::StrCat(nullptr) and compiled with clang -std=c++17 should repro. Here's a runnable repro if it's helpful:

git clone https://github.com/skye/strcat_segfault
cd strcat_segfault
CC=clang BAZEL_CXXOPTS="-std=c++17" bazel run :strcat_segfault

What version of Abseil are you using?
https://github.com/abseil/abseil-cpp/commits/lts_2021_11_02

What operating system and version are you using
Debian Rodete

What compiler and version are you using?

$ clang -v
Debian clang version 13.0.1-3+build2
Target: x86_64-pc-linux-gnu
Thread model: posix
...
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/11
Candidate multilib: .;@m64
Selected multilib: .;@m64

What build system are you using?
bazel 5.1.1

Additional context
Example segfault stacktrace:

Program received signal SIGSEGV, Segmentation fault.
0x00005555557be147 in std::char_traits<char>::length (__s=0x0) at /usr/include/c++/9/bits/char_traits.h:342
342        return __builtin_strlen(__s);
(gdb) bt
#0  0x00005555557be147 in std::char_traits<char>::length (__s=0x0) at /usr/include/c++/9/bits/char_traits.h:342
#1  0x00005555557db1ee in std::basic_string_view<char, std::char_traits<char> >::basic_string_view (this=0x7fffffffdd10, __str=0x0) at /usr/include/c++/9/string_view:124
#2  0x0000555555808bd5 in absl::lts_20211102::AlphaNum::AlphaNum (this=0x7fffffffdd10, c_str=0x0) at external/com_google_absl/absl/strings/str_cat.h:248
#3  0x0000555557447b55 in tensorflow::tpu::TryAcquireTpuLock () at external/org_tensorflow/tensorflow/core/tpu/tpu_initializer_helper.cc:133
#4  0x0000555557450245 in tensorflow::tpu::FindAndLoadTpuLibrary () at external/org_tensorflow/tensorflow/core/tpu/tpu_initializer_helper.cc:264
#5  0x0000555557447304 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535)
    at external/org_tensorflow/tensorflow/core/tpu/tpu_api_dlsym_initializer.cc:25
#6  0x0000555557447324 in _GLOBAL__sub_I_tpu_api_dlsym_initializer.cc(void) () at external/org_tensorflow/tensorflow/core/tpu/tpu_api_dlsym_initializer.cc:29
#7  0x00005555590e198d in __libc_csu_init ()
#8  0x00007ffff7879040 in __libc_start_main (main=0x5555557bdc59 <main(int, char**)>, argc=2, argv=0x7fffffffe208, init=0x5555590e1940 <__libc_csu_init>,
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe1f8) at ../csu/libc-start.c:264
#9  0x00005555557bdb9e in _start ()

Thanks for reporting the issue.

Parameters passed to absl::StrCat are used to construct absl::string_view instances.
For absl::string_view, there is a constructor that works with a null char*.
Attempting to construct an std::string_view the same way results in undefined behavior.
See #73 for more context.

To make things more complicated, Abseil defines absl::string_view as an alias to std::string_view by default, when the latter is available:

#define ABSL_OPTION_USE_STD_STRING_VIEW 2

We're discussing internally how to proceed.
Maybe using absl::NullSafeStringView like absl::Substitute could be an option.

Thanks for the fix!