3

I'm trying to write a Signal handler that gets everytime called when my programm crashes and than writes the informations the boost::stacktracer api gives me into a file on my harddrive. Writing the handler is no problem as well as crashing my programm isn't. But now I am totally unsure what functions I can use in my handler. The functions I'm going to use needs to be Async safe I get that but I just can't find a list for windows which functions are allowed to use I got a list for Linux which is pretty clear and pretty easy to understand but useless since the most functions are from <unistd.h> and this does not exist in windows or atleast not in VS2017s compiler. Since I read that <io.h> is pretty simillar to <unistd.h> I tried to achiev my goal with functions out of this header.

So I use _sopen_s(&fileHandle,"E:\\UslessStuff\\stacktracer.txt",_O_RDWR,_SH_DENYNO,_S_IWRITE);

to open a file and

  if(_write(fileHandle,&boost::stacktrace::stacktrace(),boost::stacktrace::stacktrace().size())==-1) {
switch(errno) {
  case EBADF:
    perror("Bad File Discription");
    break;
  case ENOSPC:
    perror("No Space left on Device");
    break;
  case EINVAL:
    perror("Invalid Parameter: Buffer was NULL");
    break;
   default:
     perror("Unexpectet Error");


    break;
    }
  }

for writing. So I want to no is it okay to use this functions? Also how far can I go with strings in a Signal? As you see I try to get informations from boost::stacktrace::stacktrace() which gives me a perfect result when I use it with cout << boost::stacktrace::stacktrace() but writes me just 2 RAM addresses in my Textfile when I try to write it like shown above so I think I migth need to extract the string from boost::stacktrace::stacktrace() with creating a boost::stacktrace::frame fr which would result in fr.source_file().c_str(); so it'd give me a std::string back which I probably would need to pack in a char* which really sounds like I shouldn't do it in a Signal

alovaros
  • 476
  • 4
  • 23

1 Answers1

2

There is little authoritative information on this in general, even on POSIX. Instead, I'd suggest posting to a queue/signaling a condition from inside the async handler (using safe primitives) and doing the rest elsewhere.

TTBOMK this abstraction is already present and ready-to-use in Boost:

Also, for your particular purpose it does appear that Boost Stacktrace has helper functions that are expressly async-safe: Handling terminates, aborts and Segmentation Faults:

#include <signal.h>     // ::signal, ::raise
#include <boost/stacktrace.hpp>

void my_signal_handler(int signum) {
    ::signal(signum, SIG_DFL);
    boost::stacktrace::safe_dump_to("./backtrace.dump");
    ::raise(SIGABRT);
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • First thank you (again) I gonna have a look at `signal_set`. Yeah I know that boost contains ` boost::stacktrace::safe_dump_to("")` I worked myself througth the tutorial the problem is that `safe_dump_to()` is deactivated and shouldn't be used on windows since it crashes. *Async safe dumping into files on Windows OS was causing hangs on some platforms and now is disabled #33. Users are encouraged to update to the latest Boost release.* From the 1.67.0 Patchnotes. I would be damn Happy if this would just work haha :D – alovaros Jun 20 '18 at 15:28
  • @alovaros I'd look at the `signal_set` then. Perhaps you can just use condition variable instead, depending on your program. Also, perhaps you can compare with some ... more "mature" (read: old) libraries that might fit your requirements... https://stackoverflow.com/questions/691719/c-display-stack-trace-on-exception I can't say I have much experience there, so: good luck! – sehe Jun 20 '18 at 15:35
  • Okay thank you very much again :) I'll hopefully will finish this project soon. Gonna read me through the alternatives (lol even c++11 hase such functionallity....) – alovaros Jun 20 '18 at 15:46