On 15/07/2015 15:30, Matthias Klose wrote:
On 07/15/2015 05:21 PM, rle...@codelibre.net wrote:
Matthias Klose <d...@debian.org> (2015-02-12):
The following tests FAILED:
Errors while running CTest
          2 - sbuild-chroot-chroot (Failed)
          6 - sbuild-run-parts (Failed)
make[2]: *** [test] Error 8
Makefile:117: recipe for target 'test' failed
make[2]: Leaving directory '/«PKGBUILDDIR»/debian/build'
make[1]: *** [install-arch] Error 2
debian/rules:83: recipe for target 'install-arch' failed
make[1]: Leaving directory '/«PKGBUILDDIR»'
make: *** [binary-arch] Error 2
debian/rules:39: recipe for target 'binary-arch' failed
dpkg-buildpackage: error: fakeroot debian/rules binary-arch gave error
exit status 2

FWIW this isn't specific to gcc-5, the same happens with 4.9 in a sid
development chroot.

I have tried reproducing this in an unstable VM, and I can certainly do
so.  It's throwing instantiating a static regex instance.

However, I can't reproduce as a minimal testcase.  Constructing the same
regex, either as an auto or static variable in a function scope or as a
global works perfectly.

std::regex was broken in earlier GCC releases, so we used boost::regex,

could you recheck with GCC 5? I won't say that it is completely fixed, but there
were a lot of fixes and updates.

but I thought it was functional in these compiler versions.  The fact that
the minimal testcase works hints that it's a problem in schroot, but I'm
unable to see why the code is problematic.

IIRC it's throwing here:
https://github.com/codelibre-net/schroot/blob/76a85f0fb34d39f796185d296fadde81b79a3948/lib/schroot/util.cc#L157
or here:
https://github.com/codelibre-net/schroot/blob/76a85f0fb34d39f796185d296fadde81b79a3948/lib/schroot/util.cc#L157

We are wrapping the regex implementation here:
https://github.com/codelibre-net/schroot/blob/76a85f0fb34d39f796185d296fadde81b79a3948/lib/schroot/regex.h
(to support boost/tr1/std regex)
but the failure is in the constructor of the wrapped type, and I couldn't
reproduce with the wrapper or a std::regex.

fwiw, I also tried with boost1.57 from experimental, and got the same test 
failures.

OK, some further investigation has shown what the exact error is. It looks like a GCC bug. Please see the attached source file testcase. This regex is failing:

  std::regex("^[a-z0-9][a-z0-9-]*$", std::regex::extended);

however this one works:

  std::regex("^[a-z0-9][-a-z0-9]*$", std::regex::extended);

GCC 4.9 (Debian 8): fails
GCC 5 (Debian sid): fails
clang++ 3.4 (FreeBSD 10.1-RELEASE): works
clang++ 3.4 (FreeBSD ports): works
clang++ 3.5 (FreeBSD ports): works
clang++ 3.6 (FreeBSD ports): works
clang++ 3.6 (MacOS): works

Note it fails when std::regex::extended is used, but works correctly without. So looks like it can be patched with the above change in the interim, but this bug should likely be cloned and assigned to gcc?


Regards,
Roger
#include <cassert>
#include <regex>
#include <iostream>
#include <stdexcept>

int main()
{
  try
    {
      // These three are OK:
      static std::regex lanana_namespace("^[a-z0-9]+$", std::regex::extended);
      static std::regex lsb_namespace("^_?([a-z0-9_.]+-, 
std::regex::extended)+[a-z0-9]+$");
      static std::regex debian_dpkg_conffile_cruft("dpkg-(old|dist|new|tmp, 
std::regex::extended)$");
    }
  catch(const std::regex_error& e)
    {
      std::cout <<"E0: " << e.what() << std::endl;
    }

  try
    {
      // This fails with regex_error:
      static std::regex debian_cron_namespace("^[a-z0-9][a-z0-9-]*$", 
std::regex::extended);
      assert(std::regex_match("test", debian_cron_namespace));
      assert(!std::regex_match("-a", debian_cron_namespace));
      assert(std::regex_match("a-", debian_cron_namespace));
    }
  catch(const std::regex_error& e)
    {
      std::cout <<"E1: " << e.what() << std::endl;
    }

  try
    {
      // This modified version works by moving the hyphen to the start of
      // the square bracket, even though the meaning is the same:
      static std::regex debian_cron_namespace_ok("^[a-z0-9][-a-z0-9]*$", 
std::regex::extended);
      assert(std::regex_match("test", debian_cron_namespace_ok));
      assert(!std::regex_match("-a", debian_cron_namespace_ok));
      assert(std::regex_match("a-", debian_cron_namespace_ok));
    }
  catch(const std::regex_error& e)
    {
      std::cout <<"E2: " << e.what() << std::endl;
    }
}

Reply via email to