Comments (4)
That's a bit of a nasty one. Do you know which version of libstdc++ is running?
I could try and reproduce it by building a shared library that I dlopen.
I think if it is a static initialisation problem then the alternative is to either do what you said with a singleton or to wrap them up in some object that is only constructed when you construct an options parser.
from cxxopts.
Do you know which version of libstdc++ is running?
Based on the backtrace it looks like libstdc++ is not linked statically into the indexed_bzip2 shared library because /usr/lib/x86_64-linux-gnu/libstdc++.so.6
is used. This backtrace was supposedly from inside an Ubuntu 22.04 Docker image. Based on that information and the so path, which also exists on my local Ubuntu 22.04, it seems to be provided by this package libstdc++6:amd64
and links to libstdc++.so.6.0.30
. I'd say that version 6.0.30 is being used.
I could try and reproduce it by building a shared library that I dlopen.
According to the user, a simple import via Python did not even trigger the issue instead it only happened deep inside some more complex software. Unfortunately there is no minimal reproducer known to me yet. It might be something that happens because of multiple dlopens, maybe even from multiple threads?
from cxxopts.
I have updated my library to use v3.1.1 and took a look into avoiding those static variables. I noticed that each regex variable is only ever used exactly inside one function, so it isn't the major refactor I thought it to be and simply making those global variables static function-scope variables should circumvent the problem without any downsides. I guess the only downside would be that they are not listed right next to each other but I guess even that could be fixed by crating static constexpr string_view
or const char*
global variables holding the pattern and then initialize the static function-scope regexes with those patterns.
Here is my patch, trying to be least invasive. It still contains trailing whitespace fixes because my editor removes those automatically.
diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp
index b789a5c..aff0d44 100644
--- a/include/cxxopts.hpp
+++ b/include/cxxopts.hpp
@@ -55,8 +55,8 @@ THE SOFTWARE.
#define CXXOPTS_LINKONCE_CONST __declspec(selectany) extern
#define CXXOPTS_LINKONCE __declspec(selectany) extern
#else
-#define CXXOPTS_LINKONCE_CONST
-#define CXXOPTS_LINKONCE
+#define CXXOPTS_LINKONCE_CONST
+#define CXXOPTS_LINKONCE
#endif
#ifndef CXXOPTS_NO_REGEX
@@ -758,29 +758,31 @@ inline ArguDesc ParseArgument(const char *arg, bool &matched)
namespace {
CXXOPTS_LINKONCE
-std::basic_regex<char> integer_pattern
- ("(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
+const char* const integer_pattern =
+ "(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)";
CXXOPTS_LINKONCE
-std::basic_regex<char> truthy_pattern
- ("(t|T)(rue)?|1");
+const char* const truthy_pattern =
+ "(t|T)(rue)?|1";
CXXOPTS_LINKONCE
-std::basic_regex<char> falsy_pattern
- ("(f|F)(alse)?|0");
+const char* const falsy_pattern =
+ "(f|F)(alse)?|0";
CXXOPTS_LINKONCE
-std::basic_regex<char> option_matcher
- ("--([[:alnum:]][-_[:alnum:]\\.]+)(=(.*))?|-([[:alnum:]].*)");
+const char* const option_pattern =
+ "--([[:alnum:]][-_[:alnum:]\\.]+)(=(.*))?|-([[:alnum:]].*)";
CXXOPTS_LINKONCE
-std::basic_regex<char> option_specifier
- ("([[:alnum:]][-_[:alnum:]\\.]*)(,[ ]*[[:alnum:]][-_[:alnum:]]*)*");
+const char* const option_specifier_pattern =
+ "([[:alnum:]][-_[:alnum:]\\.]*)(,[ ]*[[:alnum:]][-_[:alnum:]]*)*";
CXXOPTS_LINKONCE
-std::basic_regex<char> option_specifier_separator(", *");
+const char* const option_specifier_separator_pattern = ", *";
} // namespace
inline IntegerDesc SplitInteger(const std::string &text)
{
+ static const std::basic_regex<char> integer_matcher(integer_pattern);
+
std::smatch match;
- std::regex_match(text, match, integer_pattern);
+ std::regex_match(text, match, integer_matcher);
if (match.length() == 0)
{
@@ -804,15 +806,17 @@ inline IntegerDesc SplitInteger(const std::string &text)
inline bool IsTrueText(const std::string &text)
{
+ static const std::basic_regex<char> truthy_matcher(truthy_pattern);
std::smatch result;
- std::regex_match(text, result, truthy_pattern);
+ std::regex_match(text, result, truthy_matcher);
return !result.empty();
}
inline bool IsFalseText(const std::string &text)
{
+ static const std::basic_regex<char> falsy_matcher(falsy_pattern);
std::smatch result;
- std::regex_match(text, result, falsy_pattern);
+ std::regex_match(text, result, falsy_matcher);
return !result.empty();
}
@@ -821,22 +825,25 @@ inline bool IsFalseText(const std::string &text)
// (without considering which or how many are single-character)
inline OptionNames split_option_names(const std::string &text)
{
- if (!std::regex_match(text.c_str(), option_specifier))
+ static const std::basic_regex<char> option_specifier_matcher(option_specifier_pattern);
+ if (!std::regex_match(text.c_str(), option_specifier_matcher))
{
throw_or_mimic<exceptions::invalid_option_format>(text);
}
OptionNames split_names;
+ static const std::basic_regex<char> option_specifier_separator_matcher(option_specifier_separator_pattern);
constexpr int use_non_matches { -1 };
auto token_iterator = std::sregex_token_iterator(
- text.begin(), text.end(), option_specifier_separator, use_non_matches);
+ text.begin(), text.end(), option_specifier_separator_matcher, use_non_matches);
std::copy(token_iterator, std::sregex_token_iterator(), std::back_inserter(split_names));
return split_names;
}
inline ArguDesc ParseArgument(const char *arg, bool &matched)
{
+ static const std::basic_regex<char> option_matcher(option_pattern);
std::match_results<const char*> result;
std::regex_match(arg, result, option_matcher);
matched = !result.empty();
@@ -1551,7 +1558,7 @@ class ParseResult
Iterator(const Iterator&) = default;
// GCC complains about m_iter not being initialised in the member
-// initializer list
+// initializer list
CXXOPTS_DIAGNOSTIC_PUSH
CXXOPTS_IGNORE_WARNING("-Weffc++")
Iterator(const ParseResult *pr, bool end=false)
from cxxopts.
Fixed with #406.
from cxxopts.
Related Issues (20)
- Branch Name: main HOT 1
- About a new tag-release HOT 1
- feature request/question: support the one dash as argument HOT 2
- Feature request: value pairs or tuples HOT 1
- Renaming of OptionException should be mentioned in changelog HOT 1
- Allow "G", "M" and 'k' when parsing arguments HOT 2
- Getting a sign-conversion warning/error with clang 14 and CXXOPTS_USE_UNICODE_HELP ON HOT 2
- A proposition to implement any complex rule on the arguments
- unannotated fall-through between switch labels HOT 3
- Are unrecognized options supported? HOT 1
- In Linux systems, the tilde symbol (~) cannot be automatically expanded to "/home/user1," HOT 4
- -option Error message. I think we should not just report command āpā error. HOT 5
- Report a typo in README.md doc(in master branch) HOT 1
- What is the use of constructor parameters in options("MyProgram", "One line description of MyProgram")? HOT 3
- Filtered argc/argv HOT 3
- cxxopts-3.2.0 breaks in c++20 mode: invalid operands to binary expression ('std::stringstream' (aka 'basic_stringstream<char>') and 'std::optional<bool>' HOT 8
- Add + as an argument indicator
- short arg unable to accept argument. HOT 2
- Sub-options support HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ššš
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cxxopts.