[Boost::ext].SML: Segmentation fault in guard with Mingw64 GCC, debug build - c++

Code
#include <sml.hpp>
namespace {
struct Event {
bool pressed;
};
struct Guard1 {
[[nodiscard]] bool operator()(const Event& e) const {
return e.pressed;
}
} guard1;
struct Guard2 {
[[nodiscard]] bool operator()(const Event& e) const {
return true;
}
} guard2;
struct Guard3 {
[[nodiscard]] bool operator()(const Event& e) const {
return true;
}
} guard3;
}// namespace
namespace sml = boost::sml;
struct Fsm {
struct State {};
auto operator()() const {
using namespace boost::sml;
return make_transition_table(
// clang-format off
*state<State> + event<Event>[guard1 && guard2 && guard3] = state<State>
// clang-format on
);
}
};
int main() {
boost::sml::sm<Fsm> fsm{};
fsm.process_event(Event{});
}
Expected Behavior
No segmentation fault.
Actual Behavior
Segmentation fault when accessing the pressed field in Guard1.
Process finished with exit code -1073741819 (0xC0000005)
Event address is still ok in front::transition::execute:
But in front::call::execute it gets corrupted:
If I remove one of the guard, it works fine.
Steps to Reproduce the Problem
use gcc from MSYS2, gcc --version gcc.exe (Rev2, Built by MSYS2 project) 12.1.0
build with -g -std=gnu++20
run
Specifications
Version: 1.1.4, 1.1.5
Platform: Windows, GCC 12.1.0 (MSYS2 mingw-w64-x86_64-gcc)

Related

Is clang-11's invocation of <coroutine> headers via -fcoroutines flag?

I'm trying to compile a .cpp file that uses the coroutine library with the command.
clang-11 -std=c++20 -stdlib=libstdc++ main.cpp
I get an error like this:
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/coroutine:295:2: error: "the coroutine header requires -fcoroutines"
#error "the coroutine header requires -fcoroutines"
So, I add the flag:
clang-11 -std=c++20 -stdlib=libstdc++ main.cpp -fcoroutines
Now, I get the error:
clang-11: error: unknown argument: '-fcoroutines'
Is this a bug?
The closest question is here. However, I wasn't able to conclude whether a bug exists or not.
For what its worth, here's the source:
#include <iostream>
#include <coroutine>
template<typename T>
bool is_prime(T number) {
for(int i=2;i<number;i++) {
if (not i%number) return true;
}
return false;
}
class prime_iterator {
unsigned int number = 2;
public:
auto operator*() const {
return number;
}
prime_iterator& operator++() {
++number;
if (not is_prime(number)) {
co_yield number; // Trying to invoke co_yield just to see if library works.
}
return *this;
}
};
auto main() -> int {
for(prime_iterator p; *p < 30; ++p) {
std::cout << *p << " is prime";
}
}
It should be -fcoroutines-ts for clang. Unless you are building coroutine with clang mixed with libstdc++.

Clang report "constexpr if condition is not a constant expression" while GCC is ok [duplicate]

This question already has answers here:
Static member access in constant expressions
(2 answers)
Closed 2 years ago.
I'm using clang 9.0.1 and gcc 9.2.1 on x64 Linux, both with --std=c++17 (or --std=c++2a).
Gcc can build the following example without any error or warning, while clang++ reports error: constexpr if condition is not a constant expression on both if constexpr lines. (btw, on my MacBook, Apple clang-11.0.0 reports the same error too.)
MCVE:
#include <utility>
enum class TopicType {
MarketData = 'M',
Timer = 'T',
};
template<class Topic>
struct TopicBase {
constexpr static TopicType type() { return Topic::type; };
const Topic& topicImp;
explicit TopicBase(const Topic &t) : topicImp(t) {}
};
struct MarketDataTopic {
static constexpr TopicType type{TopicType::MarketData};
};
struct TimerTopic {
static constexpr TopicType type{TopicType::Timer};
};
template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {
if constexpr (topic.type() == TopicType::MarketData) { // <-- clang++ reports error here
return 1;
}
if constexpr (topic.type() == TopicType::Timer) { // and error here
return 2;
}
return -1;
}
int main(int argc, const char **argv) {
MarketDataTopic m{};
TimerTopic t{};
TopicBase<MarketDataTopic> b1{m};
TopicBase<TimerTopic> b2{t};
subscribe(std::move(b1));
return 0;
}
Online compiler https://godbolt.org/z/rARi_N has the same result.
So which compiler is right about this? And if it is an error, how to fix it for clang?
Well you can do this to make it work for clang:
template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {
using myType = TopicBase<Topic>;
if constexpr (myType::type() == TopicType::MarketData) { // <-- clang++ reports error here
return 1;
}
if constexpr (myType::type() == TopicType::Timer) { // and error here
return 2;
}
return -1;
}
Run live
Most probably that's a bug in clang. Better report it.

How do I use std::optional in C++?

I am trying to use std::optional but my code raise error.
I have specified #include <experimental/optional> and compiler options are -std=c++1z, -lc++experimental.
How to use std::experimental::optional?
The following is code:
#include <experimental/optional>
#include <iostream>
std::experimental::optional<int> my_div(int x, int y) {
if (y != 0) {
int b = x / y;
return {b};
}
else {
return {};
}
}
int main() {
auto res = my_div(6, 2);
if (res) {
int p = res.value();
std::cout << p << std::endl;
}
}
error message:
optional.cpp:17:21: error: call to unavailable member function 'value':
int p = res.value();
~~~~^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/experimental/optional:525:17: note: candidate function has been explicitly made unavailable
value_type& value()
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/experimental/optional:517:33: note: candidate function has been explicitly made unavailable
constexpr value_type const& value() const
^
1 error generated.
OS: macOS 10.12.5
Compiler version:
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Okay, after you posted your error, I could look into that (but you could have done exactly the same).
IN SHORT
This is a problem/bug with optional as provided by Apple on OSX, but there is an easy workaround.
WHAT'S GOING ON
The file /Library/Developer/CommandLineTools/usr/include/c++/v1/exper‌​imental/optional declares the offending function optional::value as
template <class _Tp>
class optional
: private __optional_storage<_Tp>
{
/* ... */
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
constexpr value_type const& value() const
{
if (!this->__engaged_)
throw bad_optional_access();
return this->__val_;
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
value_type& value()
{
if (!this->__engaged_)
throw bad_optional_access();
return this->__val_;
}
/* ... */
};
Running the preprocessor only (compiler option -E) reveals that the macros expand to
#define _LIBCPP_INLINE_VISIBILITY \
__attribute__ ((__visibility__("hidden"), __always_inline__))
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
__attribute__((unavailable))
In particular, the macro _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS is #defined in file /Library/Developer/CommandLineTools/usr/include/c++/v1/__config as
// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
// ...
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
// ...
#else
// ...
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
// ...
#endif
Thus, this is a Apple specific change from LLVM's libc++ API. As the name of the macro implies, the reason is that Apple does not make
class bad_optional_access
: public std::logic_error
{
public:
bad_optional_access() : std::logic_error("Bad optional Access") {}
virtual ~bad_optional_access() noexcept;
};
available and hence cannot implement functionality (optional::value) that depends on it. Why bad_optional_access is not provided (thereby breaking the standard) is unclear, but it may have to do with the fact that a library (dylib) must be altered to contain bad_optional_access::~bad_optional_access().
HOW TO WORK AROUND
simply use optional::operator* instead
int p = *res;
The only real difference is that no access check is done. If you need that, do it yourself
template<typename T>
T& get_value(std::experimental::optional<T> &opt)
{
if(!opt.has_value())
throw std::logic_error("bad optional access");
return *opt;
}
template<typename T>
T const& get_value(std::experimental::optional<T>const &opt)
{
if(!opt.has_value())
throw std::logic_error("bad optional access");
return *opt;
}

asio high_resolution_timer segmentation fault in async_wait

I have implemented a task queue with priority from asio examples and a timer class which use this queue. Here is the code:
priority_task_queue.h
class handler_priority_queue
{
private:
class queued_handler{
private:
size_t _priority;
std::function<void()> _function;
public:
queued_handler(size_t p, std::function<void()> f): _priority(p), _function(f){}
friend bool operator<(const queued_handler& a, const queued_handler& b){
return a._priority < b._priority;
}
void operator()() {
_function();
}
};
std::priority_queue<queued_handler> _handlers;
public:
// A generic wrapper class for handlers to allow the invocation to be hooked.
template <typename Handler> class wrapped_handler
{
private:
handler_priority_queue& _queue;
size_t _priority;
Handler _handler;
public:
handler_priority_queue& queue() {return _queue;}
size_t priority() {return _priority;}
wrapped_handler(handler_priority_queue& q, size_t p, Handler h)
: _queue(q), _priority(p), _handler(h){}
template <typename ...Args>
void operator()(Args&&... args){
_handler(std::forward<Args>(args)...);
}
};
template <typename Handler> wrapped_handler<Handler> wrap(size_t priority, Handler handler){
return wrapped_handler<Handler>(*this, priority, handler);
}
void add(size_t priority, std::function<void()> function);
void execute_all();
void execute_one();
bool empty();
};
// Custom invocation hook for wrapped handlers.
template <typename Function, typename Handler>
void asio_handler_invoke(Function f, handler_priority_queue::wrapped_handler<Handler>* h){
h->queue().add(h->priority(), f);
std::cout<<"LLAMANDO AL INVOKE"<<std::endl; //BORRAR!!
}
class C_priority_task_queue{
private:
asio::io_service& _io;
handler_priority_queue _pri_queue;
public:
template <typename Handler> handler_priority_queue::wrapped_handler<Handler> wrap(int priority, Handler handler){
return _pri_queue.wrap(priority, handler);
}
explicit C_priority_task_queue(asio::io_service& io): _io(io){}
C_priority_task_queue(C_priority_task_queue const&) = delete;
C_priority_task_queue& operator =(C_priority_task_queue const&) = delete;
asio::io_service& io() {return _io;}
void run();
};
priority_task_queue.cpp
void handler_priority_queue::add(size_t priority, std::function<void()> function){
_handlers.push(queued_handler(priority, function));
}
void handler_priority_queue::execute_one(){
if(!_handlers.empty()){
queued_handler handler = _handlers.top();
handler();
_handlers.pop();
}
}
bool handler_priority_queue::empty(){
return _handlers.empty();
}
void C_priority_task_queue::run(){
while (_io.run_one())
{
_io.poll();
while(!_pri_queue.empty())
{
_io.poll();
_pri_queue.execute_one();
}
}
}
base_timer.h
class C_timer {
private:
asio::high_resolution_timer _timer;
uint8_t _timer_id;
C_priority_task_queue& _prio_queue;
void timer_handler_internal(const asio::error_code& e, uint8_t timer_id, const uint64_t sched_time);
virtual void timer_handler(const uint64_t sched_time)=0;
public:
size_t _priority;
explicit C_timer(C_priority_task_queue& prio_queue, size_t priority);
virtual ~C_timer();
void set_timer(uint64_t sched_time);
int cancel();
};
base_timer.cpp
C_timer::C_timer(C_priority_task_queue& prio_queue, size_t priority):
_timer(prio_queue.io()), _timer_id(0), _prio_queue(prio_queue), _priority(priority){}
C_timer::~C_timer(){}
void C_timer::set_timer(uint64_t sched_time){
++_timer_id;
_timer.expires_at(std::chrono::time_point<std::chrono::high_resolution_clock>(std::chrono::milliseconds(sched_time)));
_timer.async_wait(_prio_queue.wrap(_priority, std::bind(&C_timer::timer_handler_internal, this,
std::placeholders::_1/*error*/, _timer_id, sched_time)));
}
int C_timer::cancel(){
++_timer_id;
return _timer.cancel();
}
void C_timer::timer_handler_internal(const asio::error_code& e, uint8_t timer_id,
const uint64_t sched_time){
if(e==asio::error::operation_aborted || timer_id != _timer_id){
return;
}
timer_handler(sched_time);
}
test class
class C_timer_test: public C_timer{
private:
int _period;
virtual void timer_handler(const uint64_t sched_time) override{
std::cout<<"timer fired"<<std::endl;
uint64_t current_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
set_timer(current_time + _period);
}
public:
C_timer_test(C_priority_task_queue& prio_queue, int priority, int period):C_timer(prio_queue, priority), _periodo(period){}
virtual ~C_timer_test(){}
void run(uint64_t delay=0){
uint64_t time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
set_timer(time + delay);
}
};
The problem is if I execute this :
int main()
{
asio::io_service io;
C_priority_task_queue prio_queue(io);
asio::io_service::work w(io);
C_timer_test ti1(prio_queue, 0, 2000);
ti1.run();
prio_queue.run();
return 0;
}
I get a segmentation fault.
However, if I execute the following code it works fine:
int main()
{
asio::io_service io;
C_priority_task_queue prio_queue(io);
asio::high_resolution_timer _timer1(io);
asio::io_service::work w(io);
C_timer_test ti1(prio_queue, 0, 2000);
ti1.run();
prio_queue.run();
return 0;
}
The only diference between both piece of code is in the second main I have added the following line asio::high_resolution_timer _timer1(io); that I haven't use in any place.
Debugging the program I have found that the signal is raising in this line:
func_(&owner, this, ec, bytes_transferred); in file task_io_service_operation.hpp
I am using asio version 1.10.6.
Any suggestion that what could be happening?
The backtrace from gdb:
gdb ./main
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
This GDB was configured as "i686-linux-gnu".
(gdb) r
[libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0805f0d4 in ?? ()
(gdb) backtrace
#0 0x0805f0d4 in ?? ()
#1 0x080529fb in asio::detail::task_io_service::do_run_one (this=0x805f030, lock=..., this_thread=..., ec=...) at /src/cpp/external_lib/asio/include/asio/detail/impl/task_io_service.ipp:371
#2 0x080526ce in asio::detail::task_io_service::run_one (this=0x805f030, ec=...) at /src/cpp/external_lib/asio/include/asio/detail/impl/task_io_service.ipp:169
#3 0x08052c68 in asio::io_service::run_one (this=0xbffff08c) at /src/cpp/external_lib/asio/include/asio/impl/io_service.ipp:71
#4 0x08051f32 in C_priority_task_queue::run (this=0xbffff094) at priority_task_queue.cpp:19
#5 0x08049ac3 in main () at main.cpp:46
And here there is the MakeFile:
TARGET=main
SOURCES= main.cpp base_timer.cpp priority_task_queue.cpp
SOURCE_DIR=.
INCLUDE_LIB= -L/src/cpp/libcore
INCLUDE_DIR=-I/src/cpp/external_lib/asio/include \
-I/src/cpp/libcore/include
INSTALL_DIR=.
LIB=-pthread
CXX=g++
CFLAGS=-Wall -fexceptions -fpermissive -std=c++11 -DASIO_STANDALONE
CFLAGS_DEBUG = -g3 -DDEBUG
OBJDIR_DEBUG=obj
BINDIR_DEBUG=.
OBJECTS_DEBUG:= $(addprefix $(OBJDIR_DEBUG)/,$(SOURCES:.cpp=.o))
all: debug
$(OBJDIR_DEBUG)/%.o: $(SOURCE_DIR)/%.cpp
#test -d $(OBJDIR_DEBUG) || mkdir -p $(OBJDIR_DEBUG)
$(CXX) $(CFLAGS) $(CFLAGS_DEBUG) $(INCLUDE_DIR) -c $< -o $#
debug: $(OBJECTS_DEBUG)
#test -d $(BINDIR_DEBUG) || mkdir -p $(BINDIR_DEBUG)
$(CXX) -o $(BINDIR_DEBUG)/$(TARGET) $^ $(INCLUDE_LIB) $(LIB)
UPDATE
I my investigation, I have found that if I define the base_timer members (basically asio::high_resolution_timer) initializations in the .h, the code runs ok, but if I do this in the .cpp, the code crash.
I mean,
explicit C_timer(C_priority_task_queue& prio_queue, size_t priority):
_timer(prio_queue.io()), _timer_id(0), _prio_queue(prio_queue), _priority(priority){}
in .h works, but
C_timer::C_timer(C_priority_task_queue& prio_queue, size_t priority):
_timer(prio_queue.io()), _timer_id(0), _prio_queue(prio_queue), _priority(priority){}
in .cpp fails
Except for "unnatural" juggling with chrono (timepoint or duration, pick one!) the code looks ok. I can't reproduce any failure (GCC, linux):
Live On Coliru
If adding random variables make problems appear/disappear, you should think of Undefined Behaviour, use static analysis, valgrind/purify/... and code scrutiny to find your culprit. Valgrind, ASAN and UBSAN ran clean on my PC
#sehe thanks for your effort. The diference is If I put every code into a single file, main.cpp, it runs, but if I separate into several files, the problem still there. In other hand, If I instanciate a high_resolution_timer object in the main.cpp, no matter the place (inside main(), in separate function that never is called, ...) it runs, but without it, a segmentation fault is raised.
That's great: you have found a potential source of the UB: look at the use of static variables or inline functions that are not ODR-safe. (Double check all translation units are using the same compiler flags).
Also, keep in mind UB is UNDEFINED, so like adding an unrelated _timer1 changes the apparent behaviour (without changing the source of UB) the same thing could make it appear to work.
The fact that it runs clean on my machine tells you that this would have to be a platform-specific source of UB
The problem was that I had been using the version 1.10.2 of the library and it seems there was a bug.
I have updated to the last version 1.10.6 and now it runs ok.

c++ exception are not caught by catch(exception type)

Here is a piece of code that I have my exception in:
try {
hashTable->lookup(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo, dummyFrame);
}
catch (HashNotFoundException *e) {
}
catch (HashNotFoundException &e) {
}
catch (HashNotFoundException e) {
}
catch (...) {
}
Exception is generated within hashTable->lookup like that:
throw HashNotFoundException(file->filename(), pageNo);
Here is hashTable-lookup method signature
void BufHashTbl::lookup(const File* file, const PageId pageNo, FrameId &frameNo)
Exception escalates to top level like it's nobody's business.
I am using Mac(Lion) and Xcode(g++ for compiler)
Any thoughts would be appreciated.
Thanks!
We really need a complete example / further info to diagnose this for you.
For example the following version of the code compiles and works for me, outputing HashNotFoundException &
Note the code has some minor changes from your original, but they should not be material.
However it does generate the following warning:
example.cpp: In function ‘int main()’:
example.cpp:42: warning: exception of type ‘HashNotFoundException’ will be caught
example.cpp:38: warning: by earlier handler for ‘HashNotFoundException’
I'm compiling using i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) on OS X 10.8.5
#include <iostream>
#include <sstream>
struct BadgerDbException {};
struct PageId {};
struct FrameId {};
struct HashNotFoundException : public BadgerDbException {
std::string name;
PageId pageNo;
HashNotFoundException(const std::string& nameIn, PageId pageNoIn)
: BadgerDbException(), name(nameIn), pageNo(pageNoIn) {
}
};
struct HashTable {
void lookup(void* file, const PageId pageNo, FrameId &frameNo) {
throw HashNotFoundException("a file", pageNo);
}
};
int main() {
HashTable * hashTable = new HashTable;
PageId a_Page_ID;
FrameId dummyFrame;
try {
FrameId dummyFrame;
hashTable->lookup(NULL, a_Page_ID, dummyFrame);
}
catch (HashNotFoundException *e) { std::cout<<"HashNotFoundException *"<<std::endl;}
catch (HashNotFoundException &e) { std::cout<<"HashNotFoundException &"<<std::endl;}
catch (HashNotFoundException e) { std::cout<<"HashNotFoundException"<<std::endl; }
catch (...) { std::cout<<"... exception"<<std::endl; }
}