clang++ regex_replace always segfaults with -O3

Bug #1748344 reported by corey taylor
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
llvm-defaults (Ubuntu)
Won't Fix
Undecided
Unassigned

Bug Description

Calling regex_replace with -O3 will crash no matter the input. This seems to have started occurring after an apt-get upgrade, but I cannot say for sure exactly what package update might have caused it. We were able to run similar code in previous builds of 16.04.

If you compile without -O3, it runs.

clang++ --std=c++14 -O3 test.cpp

test.cpp:

#include <regex>
#include <string>
#include <iostream>

int main() {
    const std::string& output = regex_replace("", std::regex(""), "");
    std::cout << output << "\n";
    return 0;
}

Description: Ubuntu 16.04.3 LTS
Release: 16.04

clang:
  Installed: 1:3.8-33ubuntu3.1
  Candidate: 1:3.8-33ubuntu3.1
  Version table:
 *** 1:3.8-33ubuntu3.1 500
        500 http://us.archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages
        100 /var/lib/dpkg/status
     1:3.8-33ubuntu3 500
        500 http://us.archive.ubuntu.com/ubuntu xenial/universe amd64 Packages

ProblemType: Bug
DistroRelease: Ubuntu 16.04
Package: clang 1:3.8-33ubuntu3.1
ProcVersionSignature: Ubuntu 4.13.0-32.35~16.04.1-generic 4.13.13
Uname: Linux 4.13.0-32-generic x86_64
NonfreeKernelModules: nvidia_uvm nvidia_drm nvidia_modeset nvidia
ApportVersion: 2.20.1-0ubuntu2.15
Architecture: amd64
CurrentDesktop: Unity
Date: Thu Feb 8 20:23:48 2018
InstallationDate: Installed on 2017-08-17 (175 days ago)
InstallationMedia: Ubuntu 16.04.3 LTS "Xenial Xerus" - Release amd64 (20170801)
ProcEnviron:
 LANGUAGE=en_US
 PATH=(custom, no user)
 XDG_RUNTIME_DIR=<set>
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: llvm-defaults
UpgradeStatus: No upgrade log present (probably fresh install)

Revision history for this message
corey taylor (corey-taylor) wrote :
Revision history for this message
corey taylor (corey-taylor) wrote :

libstdc++-5-dev:
  Installed: 5.4.0-6ubuntu1~16.04.6
  Candidate: 5.4.0-6ubuntu1~16.04.6
  Version table:
 *** 5.4.0-6ubuntu1~16.04.6 500
        500 http://us.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     5.4.0-6ubuntu1~16.04.4 500
        500 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages
     5.3.1-14ubuntu2 500
        500 http://us.archive.ubuntu.com/ubuntu xenial/main amd64 Packages

Revision history for this message
Sylvestre Ledru (sylvestre) wrote :

3.8 is pretty old. you should try with a more recent version (https://apt.llvm.org/ can help with that).

Anyway, I cannot reproduce the issue from 3.8 to 7.

Changed in llvm-defaults (Ubuntu):
status: New → Won't Fix
Revision history for this message
corey taylor (corey-taylor) wrote :

I reported it because it is the default clang installed for 16.04 which is the only clang we can expect the user to have.

Revision history for this message
corey taylor (corey-taylor) wrote :

Just for historical record for anyone who search this, I was able to reproduce this with clang 4, 5 and 6.

I can only assume it is an issue with the version of libstdc++-dev pushed to 16.04.03.

Running the resulting executable always triggers a segmentation fault with -03 but runs correctly without.

Revision history for this message
corey taylor (corey-taylor) wrote :

I think the reduces test case is invalid - std::regex("") - although it had the same crash signature as the real world crash.

Oh well, sorry for the spam.

Revision history for this message
Sylvestre Ledru (sylvestre) wrote :

Please provide more information like the back trace.

Revision history for this message
corey taylor (corey-taylor) wrote :
Download full text (4.4 KiB)

Here is updated information if you are interested. I realize the recommendation is probably to move to libc++.

This is using clang++-6.0. Updated test case regex.

clang++-6.0 -std=c++14 -O3 -g test.cpp

--
#include <regex>
#include <string>
#include <iostream>

int main() {
    const std::string& output = regex_replace("test test", std::regex("^test"), "hi");
    std::cout << output << "\n";
    return 0;
}
--

Crash:

* thread #1: tid = 7900, 0x0000000000418d9b a.out`std::__cxx11::sub_match<char const*>::compare(std::__cxx11::sub_match<char const*> const&) const [inlined] std::__cxx11::sub_match<char const*>::str(this=<unavailable>) const at regex.h:867, name = 'a.out', stop reason = signal SIGSEGV: invalid address (fault address: 0xffffffffffffffc8)
    frame #0: 0x0000000000418d9b a.out`std::__cxx11::sub_match<char const*>::compare(std::__cxx11::sub_match<char const*> const&) const [inlined] std::__cxx11::sub_match<char const*>::str(this=<unavailable>) const at regex.h:867
   864 string_type
   865 str() const
   866 {
-> 867 return this->matched
   868 ? string_type(this->first, this->second)
   869 : string_type();
   870 }

Backtrace:

* thread #1: tid = 7900, 0x0000000000418d9b a.out`std::__cxx11::sub_match<char const*>::compare(std::__cxx11::sub_match<char const*> const&) const [inlined] std::__cxx11::sub_match<char const*>::str(this=<unavailable>) const at regex.h:867, name = 'a.out', stop reason = signal SIGSEGV: invalid address (fault address: 0xffffffffffffffc8)
  * frame #0: 0x0000000000418d9b a.out`std::__cxx11::sub_match<char const*>::compare(std::__cxx11::sub_match<char const*> const&) const [inlined] std::__cxx11::sub_match<char const*>::str(this=<unavailable>) const at regex.h:867
    frame #1: 0x0000000000418d9b a.out`std::__cxx11::sub_match<char const*>::compare(this=<unavailable>, __s=0xffffffffffffffb8) const + 203 at regex.h:883
    frame #2: 0x000000000041633a a.out`std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::regex_replace<std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char const*, std::__cxx11::regex_traits<char>, char>(std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char const*, char const*, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, char const*, std::regex_constants::match_flag_type) [inlined] bool std::__cxx11::operator==<char const*>(__lhs=<unavailable>, __rhs=<unavailable>) + 12 at regex.h:938
    frame #3: 0x000000000041632e a.out`std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > std::regex_replace<std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char const*, std::__cxx11::regex_traits<char>, char>(std::back_insert_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, char const*, char const*, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, char const*, std::regex_consta...

Read more...

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.