-1

I am running the following code and instead of catching my exception the program aborts. I am using Bazel and my compiler is GCC (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0.

I have a similar issue that crops up with boost::interrupt_exception. However, I cannot reproduce that one as easily.

#include <iostream>
#include <stdexcept>
#include <system_error>
#include <string>
#include <vector>
#include <sstream>


template<typename Base>
struct wallet_error_base : public Base
{
    const std::string& location() const { return m_loc; }

    std::string to_string() const
    {
        std::ostringstream ss;
        ss << m_loc << ':' << typeid(*this).name() << ": " << Base::what();
        return ss.str();
    }

protected:
    wallet_error_base(std::string&& loc, const std::string& message)
            : Base(message)
            , m_loc(loc)
    {
    }

private:
    std::string m_loc;
};


typedef wallet_error_base<std::runtime_error> wallet_runtime_error;
//----------------------------------------------------------------------------------------------------
struct wallet_internal_error : public wallet_runtime_error
{
    explicit wallet_internal_error(std::string&& loc, const std::string& message)
            : wallet_runtime_error(std::move(loc), message)
    {
    }
};

template<typename TException, typename... TArgs>
void throw_wallet_ex(std::string&& loc, const TArgs&... args)
{
    TException e(std::move(loc), args...);
    throw e;
}

#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)

#define THROW_WALLET_EXCEPTION(err_type, ...)                                                               \
  do {                                                                                                      \
    throw_wallet_ex<err_type>(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__);               \
  } while(0)                                                                                                \



int main() {

  try {
      THROW_WALLET_EXCEPTION(wallet_internal_error, "invalid password");
  }  catch (const std::exception& ex) {
      std::cout << "Caught" << std::endl;
  }

  return 0;
}

The end of strace of it is as follows.

msync(0x7ffc71bf0000, 4096, MS_ASYNC)   = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
getpid()                                = 41149
gettid()                                = 41149
tgkill(41149, 41149, SIGABRT)           = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=41149, si_uid=0} ---
+++ killed by SIGABRT (core dumped) +++

My build file:

cc_binary(
    name = "cannot_catch_exception",
    srcs = [
        "cannot_catch_exception.cpp",
    ],
    deps = [
    ],
)

I don't think this happens with cmake or normal build systems. You can only duplicate it using Bazel

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
Keiros
  • 69
  • 1
  • 9

1 Answers1

1

Alright so the answer here was really specific to me. But basically I was linking against libunwind without using -lunwind and using the wrong version of the .a file. I was using libunwind.a rather than libunwind-x84_64.a.

Keiros
  • 69
  • 1
  • 9
  • Fine that you solved your issue. To make it a more general answer (helpful for others as well), it would be nice if you could elaborate why this issue arose specifically in Bazel in your case. Are there pit-falls in configuration you have to be aware? – Scheff's Cat Dec 22 '20 at 08:03
  • I don't think it was a bazel issue after all. I wasn't able to reproduce it after the first time it failed. I looked through every compilation flag and compared between a hand compilation and Bazel and found nothing that set off alarms. Then I went down this linking path. So if I had advice it would be that Bazel doesn't play nice with linking and can have things build successfully but really have small errors. So try to build in opt mode because it will surface subtle things like this. See: https://stackoverflow.com/questions/65411141/undefined-reference-to-boost-asio – Keiros Dec 22 '20 at 15:16