bombela / backward-cpp

A beautiful stack trace pretty printer for C++
MIT License
3.73k stars 471 forks source link

Segmentation fault (Address not mapped to object [(nil)]) on printing end #194

Closed xgdgsc closed 3 years ago

xgdgsc commented 3 years ago

It segfaults on end of printing stacktrace, on line 3975 raise(info->si_signo); .

      >  52:   LOG_INFO << reinterpret_cast<DataPipe *>(pipes[0])->print();
         53: }
         54: 
         55: int main(int argc, char **argv) {
Segmentation fault (Address not mapped to object [(nil)])

And it prints a redefinition warning if I uncomment #define BACKWARD_HAS_BFD 1

#define BACKWARD_HAS_DW 1
#define BACKWARD_HAS_BFD 1
#include "backward.hpp"

this is what I use now

bombela commented 3 years ago

You must select a single symbol resolver implementation. Take a look at the top of backward.hpp for a better understanding.

bsergean commented 3 years ago

Hi there, we are running into this error as well. Here is how we use backward:

#define BACKWARD_HAS_DW 1
#include "backward.hpp"

class SignalHandlerUtils
{
  public:
    SignalHandlerUtils() = default;

  private:
    // we only need one member variable that does everything,
    // that is signal handling registration + stackwalking + symbolication
    // the backtrace is printed by backward library on stderr
    backward::SignalHandling sh;
};

// our main just does this
int main()
{
   SignalHandlerUtils signalHandler{};
   ....
}

@bombela, is this incorrect usage ?

bsergean commented 3 years ago

We use it on Linux with a static binary + elfutils library git://sourceware.org/git/elfutils.git

bombela commented 3 years ago

Could it be the object being in main is destroyed somehow before being used? Maybe it should be a global? I am just throwing ideas here.

On Tue, 23 Feb 2021, 19:19 Benjamin Sergeant, notifications@github.com wrote:

We use it on Linux with a static binary + elfutils library git:// sourceware.org/git/elfutils.git

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bombela/backward-cpp/issues/194#issuecomment-784720664, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABUZDDWWJ3M73PUEORDUCLTARV2JANCNFSM4TATGYJQ .

bsergean commented 3 years ago

Everything is possible but that sounds unlikely. Our main is server code so we essentially never exit main.

In the past I wrote crash-handling code too, and I remember avoiding fwrite and using straight write with a file descriptor instead. fwrite is not ’signal safe’ according to the internet. I’m contemplating making a PR that would add an interface with ‘write’ for the code that prints the backtrace.

On Feb 23, 2021, at 7:39 PM, François-Xavier Bourlet notifications@github.com wrote:

Could it be the object being in main is destroyed somehow before being used? Maybe it should be a global? I am just throwing ideas here.

On Tue, 23 Feb 2021, 19:19 Benjamin Sergeant, notifications@github.com wrote:

We use it on Linux with a static binary + elfutils library git:// sourceware.org/git/elfutils.git

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bombela/backward-cpp/issues/194#issuecomment-784720664, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABUZDDWWJ3M73PUEORDUCLTARV2JANCNFSM4TATGYJQ .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bombela/backward-cpp/issues/194#issuecomment-784728683, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC2O6ULGBZPZ3AK4HZNHWQTTARYI7ANCNFSM4TATGYJQ.

bombela commented 3 years ago

Fair enough. Backward-cpp is not signal safe at all. None of the lib used to parse the debug symbols are. Making signal safe code is a pretty serious endeavor. So my take was: better have stacktrace most often, than have nothing.

Nontheless you think it's the fwrite? Any ways you comment the frwite out and test on your program?

bsergean commented 3 years ago

I actually have no clue whether it’s the fwrite, and agreed that signal safe is a pain, I hate using C function for doing string manipulation myself …

I hope I can find something and report here.

On Feb 23, 2021, at 7:39 PM, François-Xavier Bourlet notifications@github.com wrote:

Could it be the object being in main is destroyed somehow before being used? Maybe it should be a global? I am just throwing ideas here.

On Tue, 23 Feb 2021, 19:19 Benjamin Sergeant, notifications@github.com wrote:

We use it on Linux with a static binary + elfutils library git:// sourceware.org/git/elfutils.git

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bombela/backward-cpp/issues/194#issuecomment-784720664, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABUZDDWWJ3M73PUEORDUCLTARV2JANCNFSM4TATGYJQ .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bombela/backward-cpp/issues/194#issuecomment-784728683, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC2O6ULGBZPZ3AK4HZNHWQTTARYI7ANCNFSM4TATGYJQ.

davemoore22 commented 3 years ago

If you don't mind me piggy-backing onto this, I'm getting a similar error.

Here's how I'm using it (on an exception I construct an error class and inside the constructor this code is called):

backward::StackTrace st;
st.load_here(32);
backward::TraceResolver tr;
tr.load_stacktrace(st);

for (size_t i = 0; i < st.size(); ++i) {
    backward::ResolvedTrace trace = tr.resolve(st[i]);

    info_e->addText(fmt::format(
        "#{} {} {} [{}] ", i, trace.object_filename, trace.object_function, trace.addr));
}

which results in:

        130:        tr.load_stacktrace(st);
        131: 
        132:        for (size_t i = 0; i < st.size(); ++i) {
      > 133:            backward::ResolvedTrace trace = tr.resolve(st[i]);
        134: 
        135:            info_e->addText(fmt::format(
        136:                "#{} {} {} [{}] ", i, trace.object_filename, trace.object_function, trace.addr));
#0    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 1321, in backward::TraceResolverLinuxImpl<backward::trace_resolver_tag::backtrace_symbol>::resolve(backward::ResolvedTrace) [0x556bfa2747a9]
       1318:   }
       1319: 
       1320:   ResolvedTrace resolve(ResolvedTrace trace) override {
      >1321:     char *filename = _symbols[trace.idx];
       1322:     char *funcname = filename;
       1323:     while (*funcname && *funcname != '(') {
       1324:       funcname += 1;
Segmentation fault (Address not mapped to object [(nil)])
Segmentation fault (core dumped)

That all said, it all works lovely if I don't attempt to do a manual traverse and just let it fail and output to the terminal as normal, but I'd also like to capture the output and do stuff with it,

(edit: I'm running XUbuntu 20.04, gcc11.1, and link in binutils-dev and libunwind-dev and have set the defines correctly)

bombela commented 3 years ago

In your output, backward-cpp is printing the trace on a segfault... caused when accessing a resolved trace from backward-cpp! That's fun.

davemoore22 commented 3 years ago

In your output, backward-cpp is printing the trace on a segfault... caused when accessing a resolved trace from backward-cpp! That's fun.

Its all incredibly meta isn't it?

Incidentally, I'd thought I'd try to be clever and use the Printer object instead but writing it to an ostringsteam. No cigar either, alas:


Source "/home/dave/Development/wizardry/sorcery-sfml/src/error.cpp", line 135, in Sorcery::Error::Error(tgui::Gui*, Sorcery::Enums::System::Error, std::exception&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) [0x5636a6372bf9]
        132:        p.color_mode = backward::ColorMode::never;
        133:        p.address = false;
        134:        std::ostringstream out;
      > 135:        p.print(st, out);
        136:        std::string wrapped_notes = WORDWRAP(out.str(), 80);
        137:        const std::regex regex(R"([@]+)");
        138:        std::sregex_token_iterator it{wrapped_notes.begin(), wrapped_notes.end(), regex, -1};
#9    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 3992, in std::ostream& backward::Printer::print<backward::StackTrace>(backward::StackTrace&, std::ostream&) [0x5636a6378c48]
       3989:   template <typename ST> std::ostream &print(ST &st, std::ostream &os) {
       3990:     Colorize colorize(os);
       3991:     colorize.activate(color_mode);
      >3992:     print_stacktrace(st, os, colorize);
       3993:     return os;
       3994:   }
#8    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 4026, in void backward::Printer::print_stacktrace<backward::StackTrace>(backward::StackTrace&, std::ostream&, backward::Colorize&) [0x5636a62062ea]
       4023:     print_header(os, st.thread_id());
       4024:     _resolver.load_stacktrace(st);
       4025:     for (size_t trace_idx = st.size(); trace_idx > 0; --trace_idx) {
      >4026:       print_trace(os, _resolver.resolve(st[trace_idx - 1]), colorize);
       4027:     }
       4028:   }
#7    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 4079, in backward::Printer::print_trace(std::ostream&, backward::ResolvedTrace const&, backward::Colorize&) [0x5636a61ffb27]
       4076:       }
       4077:       print_source_loc(os, "   ", trace.source, trace.addr);
       4078:       if (snippet) {
      >4079:         print_snippet(os, "      ", trace.source, colorize, Color::yellow,
       4080:                       trace_context_size);
       4081:       }
       4082:     }
#6    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 4093, in backward::Printer::print_snippet(std::ostream&, char const*, backward::ResolvedTrace::SourceLoc const&, backward::Colorize&, backward::Color::type, int) [0x5636a61ffc07]
       4090:     typedef SnippetFactory::lines_t lines_t;
       4091: 
       4092:     lines_t lines = _snippets.get_snippet(source_loc.filename, source_loc.line,
      >4093:                                           static_cast<unsigned>(context_size));
       4094: 
       4095:     for (lines_t::const_iterator it = lines.begin(); it != lines.end(); ++it) {
       4096:       if (it->first == source_loc.line) {
#5    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 3823, in backward::SnippetFactory::get_snippet(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int) [0x5636a61fefd3]
       3820:   lines_t get_snippet(const std::string &filename, unsigned line_start,
       3821:                       unsigned context_size) {
       3822: 
      >3823:     SourceFile &src_file = get_src_file(filename);
       3824:     unsigned start = line_start - context_size / 2;
       3825:     return src_file.get_lines(start, context_size);
       3826:   }
#4    Source "/home/dave/Development/wizardry/sorcery-sfml/inc/backwardcpp/backward.hpp", line 3863, in backward::SnippetFactory::get_src_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [0x5636a61ff078]
       3860:   src_files_t _src_files;
       3861: 
       3862:   SourceFile &get_src_file(const std::string &filename) {
      >3863:     src_files_t::iterator it = _src_files.find(filename);
       3864:     if (it != _src_files.end()) {
       3865:       return it->second;
       3866:     }
#3    Source "/usr/include/c++/11/bits/unordered_map.h", line 869, in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, backward::SourceFile, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile> > >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [0x5636a62028c7]
        866:        */
        867:       iterator
        868:       find(const key_type& __x)
      > 869:       { return _M_h.find(__x); }
        870: 
        871: #if __cplusplus > 201703L
        872:       template<typename _Kt>
#2    Source "/usr/include/c++/11/bits/hashtable.h", line 1572, in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [0x5636a6205a8b]
       1569:     {
       1570:       __hash_code __code = this->_M_hash_code(__k);
       1571:       std::size_t __bkt = _M_bucket_index(__code);
      >1572:       return iterator(_M_find_node(__bkt, __k, __code));
       1573:     }
       1574: 
       1575:   template<typename _Key, typename _Value, typename _Alloc,
#1    Source "/usr/include/c++/11/bits/hashtable.h", line 791, in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_node(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long) const [0x5636a6209036]
        788:       _M_find_node(size_type __bkt, const key_type& __key,
        789:           __hash_code __c) const
        790:       {
      > 791:    __node_base_ptr __before_n = _M_find_before_node(__bkt, __key, __c);
        792:    if (__before_n)
        793:      return static_cast<__node_ptr>(__before_n->_M_nxt);
        794:    return nullptr;
#0    Source "/usr/include/c++/11/bits/hashtable.h", line 1810, in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, backward::SourceFile> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_before_node(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long) const [0x5636a620b20d]
       1807:            __hash_code __code) const
       1808:     -> __node_base_ptr
       1809:     {
      >1810:       __node_base_ptr __prev_p = _M_buckets[__bkt];
       1811:       if (!__prev_p)
       1812:    return nullptr;
Segmentation fault (Signal sent by the kernel [(nil)])
Segmentation fault (core dumped)
bombela commented 3 years ago

I cannot reproduce the segfault.

Ubuntu 20.04.2 LTS g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 clang version 10.0.0-4ubuntu1

Testing with: clang/g++ --std=c++11 t.cpp -lunwind -lbfd -ldl

#define BACKWARD_HAS_LIBUNWIND 1
#define BACKWARD_HAS_BFD 1
#include "backward.hpp"

using namespace backward;

void p() {
    backward::StackTrace st;
    st.load_here(32);
    backward::TraceResolver tr;
    tr.load_stacktrace(st);

    for (size_t i = 0; i < st.size(); ++i) {
        backward::ResolvedTrace trace = tr.resolve(st[i]);

        std::cout << i
            << " " <<  trace.object_filename
            << " " << trace.object_function
            << " " << trace.addr
            << " " <<  std::endl;
    }
}

int main() {
    p();
    return 0;
}
bombela commented 3 years ago

Does it behaves differently with unwind instead of libunwind?

davemoore22 commented 3 years ago

Same error with using both libunwind and the standard unwind.

I'm also using lbfd but would that make a difference?

As I said, it works beautifully if I let it do its thing when an exception occurs and print stuff out to the console and then exit.

But I would like to be handle things a bit more gracefully if possible and grab the stack trace to allow users to send it to me.

bombela commented 3 years ago

I don't think libfd makes a difference. Feel free to try them all. backward-cpp is definitively supposed to work for your use case.

Note that you can store the stacktrace with your exception, and resolve it later. Up to you.

Anyways, I cannot reproduce the segfault. If you could come up with a small reproducible example, it would be great. What about running your program under valgrind?

davemoore22 commented 3 years ago

OK, a smidgeon of clarity achieved. I use both CodeBlocks and VSCode, and I think the seg fault is caused either by something in the way Codeblocks is linking or the way I have the project setup therein; because if I compile using VSCode/make, no seg fault occurs.

That's a bit weird, that said, since as far as I can tell, my build options for both methods are identical and up until now, there's been no difference in what I use to compile and link with regards to the rest of the codebase.

Build options are pretty standard BTW, including backward.cpp for the defines, search path includes backward.hpp, debug symbols are on, and the three libraries mentioned above.

I'll continue to investigate and report back, and see how I get on with valgrind.

bombela commented 3 years ago

Try unwind instead of libunwind. I am curious if it makes any significant difference. unwind is always linked in, because its offered by the compiler runtime.

bombela commented 3 years ago

Also if you could find out the exact compiler command line invocation it would be great.

davemoore22 commented 3 years ago

OK, no difference in CodeBlocks with unwind. :-(

Compilation example: `g++ -Wredundant-decls -Wcast-align -Wunreachable-code -Wmissing-declarations -Wmissing-include-dirs -Wswitch-default -Wfatal-errors -Wextra -Wall -g -pthread -Wl,-rpath=/usr/local/lib -fpic -std=c++20 -Wpedantic -Wunused -Wignored-qualifiers -Wformat-nonliteral -Wformat=2 -Winvalid-pch -Wmissing-format-attribute -Wodr -pg -g -Iinc -Iinc/simpleini -Iinc/sqlitemoderncpp -Iinc/magicenum -Iinc/backwardcpp -Iinc/cereal -Iinc/cereal/archives -c /home/dave/Development/wizardry/sorcery-sfml/src/window.cpp -o obj/debug/src/window.o` Linkage: ` g++ -Linc/backwardcpp -o bin/debug/sorcery obj/debug/inc/backwardcpp/backward.o obj/debug/src/allocatepanel.o obj/debug/src/animation.o obj/debug/src/application.o obj/debug/src/attractmode.o obj/debug/src/attributedisplay.o obj/debug/src/banner.o obj/debug/src/camera.o obj/debug/src/castle.o obj/debug/src/character.o obj/debug/src/compendium.o obj/debug/src/component.o obj/debug/src/config.o obj/debug/src/confirm.o obj/debug/src/controloverlay.o obj/debug/src/create.o obj/debug/src/database.o obj/debug/src/dialog.o obj/debug/src/display.o obj/debug/src/edgeoftown.o obj/debug/src/engine.o obj/debug/src/entity.o obj/debug/src/error.o obj/debug/src/file.o obj/debug/src/frame.o obj/debug/src/game.o obj/debug/src/graphics.o obj/debug/src/iconstore.o obj/debug/src/infopanel.o obj/debug/src/input.o obj/debug/src/keyboard.o obj/debug/src/layout.o obj/debug/src/license.o obj/debug/src/main.o obj/debug/src/mainmenu.o obj/debug/src/manage.o obj/debug/src/map.o obj/debug/src/maptile.o obj/debug/src/menu.o obj/debug/src/operator.o obj/debug/src/options.o obj/debug/src/platform.o obj/debug/src/random.o obj/debug/src/raycaster.o obj/debug/src/resourcemanager.o obj/debug/src/roster.o obj/debug/src/spellsummary.o obj/debug/src/splash.o obj/debug/src/statusbar.o obj/debug/src/string.o obj/debug/src/system.o obj/debug/src/textfile.o obj/debug/src/tile.o obj/debug/src/tooltip.o obj/debug/src/training.o obj/debug/src/window.o -lstdc++fs -lX11 -lsfml-graphics -lsfml-audio -lsfml-network -lsfml-window -lsfml-system -lsqlite3 -lsfeMovie -ljsoncpp -lthor -lpthread -lfmt -luuid -lbfd -ldl -ltgui -lunwind -pg `
bombela commented 3 years ago

In your first segfault, you are using BACKTRACE, not BFD. But you claim that you intended to use BFD. Your command line also doesn't include the various defines for backward.hpp. This leads me to believe that you are compiling backward.hpp differently in various code object (.o). And then linking the whole thing together. I further believe that because you mentioned some defines in backward.cpp. Which only applies to this very .cpp file. The one that registers unix signal that then give you a nice printed trace. But the backward.hpp you are importing for attaching to the exception is not compiled with the same defines.

In other words: set the defines for your compilation command lines. Or set them atop backward.hpp. But not in .cpp files.

davemoore22 commented 3 years ago

ok, I'll try that!!!

davemoore22 commented 3 years ago

That worked. Removing backward.cpp from my project and moving the defines into backward.hpp was the key. I can now grab the stack to allow the users to send me the info. Thank you!!!

image

What's the best/preferred way of crediting use of the library btw?

bombela commented 3 years ago

Ah C++... It keeps you on your toes at all time. One tiny slip, and your program will do everything and anything.

If you already have an "about" dialog with a list of open sources credits, you can add a mention there if you would like. No obligation.

bombela commented 3 years ago

For anybody else reading this issue.

Make sure that you are compiling backward.hpp with the exact same defines and compilation flags throughout your program. Otherwise, the generated machine code will be incompatible at runtime.

nmaludy commented 2 years ago

@bombela i ran into this same issue, but ONLY when executed from inside backward::SignalHandling and when forcing the segfault by access to a NULL pointer.

Segmentation fault (Address not mapped to object [(nil)])
Segmentation fault (core dumped)

Digging into the source and gdb i was able to find that it was coming from https://github.com/bombela/backward-cpp/blob/master/backward.hpp#L4250

Simply commenting out that line removes the error message. I did also try using psignal(signo); instead and simply got an error message:

Segmentation Fault
Segmentation Fault (core dumped)

Some more experimentation, i tried forcefully raise(SIGSEGV) and got an error message:

Segmentation fault (Signal sent by tkill() [0x3e800063099])
Segmentation fault (core dumped)

Conclusions:

My code to reproduce this is below:

#include "backward.hpp"
using namespace backward;

void p() {
    backward::StackTrace st;
    st.load_here(32);
    backward::TraceResolver tr;
    tr.load_stacktrace(st);

    for (size_t i = 0; i < st.size(); ++i) {
        backward::ResolvedTrace trace = tr.resolve(st[i]);

        std::cout << i
            << " " <<  trace.object_filename
            << " " << trace.object_function
            << " " << trace.addr
            << " " <<  std::endl;
    }
}

int nullSegfault()
{
  int* p_junk = 0;
  int val =  *p_junk;
  return val; // have to use `val` to avoid optimizer throwing all this code away
}

void raiseSegfault()
{
  raise(SIGSEGV);
}

int main(int argc, char* argv[])
{
  // print stacktrace normally to show that it works in-process
  p();

  // register backward signal handlers to showcase the error message
  backward::SignalHandling sh;

  // comment these out to choose how to raise the signal

  // cause segfault by NULL pointer access, prints:
  // Segmentation fault (Address not mapped to object [(nil)])
  nullSegfault();

  // cause segfault by raising the signal manually, prints:
  // Segmentation fault (Signal sent by tkill() [0x3e800063099])
  raiseSegfault();
  return 0;
}

Hope this helps someone else.

bombela commented 2 years ago

I don't think it is the same issue. You are talking about some output message from psiginfo. They had a memory access error because of incompatible datastructures in memory.

Unless you are saying you got a memory access error during the execution of psiginfo?

The psiginfo() function is like psignal(), except that it displays information about the signal described by pinfo, which should point to a valid siginfo_t structure. As well as the signal description, psiginfo() displays information about the origin of the signal, and other information relevant to the signal (e.g., the relevant memory address for hardware-generated signals, the child process ID for SIGCHLD, and the user ID and process ID of the sender, for signals set using kill(2) or sigqueue(3)).

https://linux.die.net/man/3/psiginfo