The program below outputs only:
0In finally
And not the output:
0 In trans_func Caught a __try exception with SE_Exception In finally
As I expected.
#include "stdafx.h"
// crt_settrans.cpp
// compile with: /EHa
#include <stdio.h>
#include <windows.h>
#include <eh.h>
void SEFunc();
void trans_func( unsigned int, EXCEPTION_POINTERS* );
class SE_Exception
{
private:
unsigned int nSE;
public:
SE_Exception() {}
SE_Exception( unsigned int n ) : nSE( n ) {}
~SE_Exception() {}
unsigned int getSeNumber() { return nSE; }
};
int main( void )
{
try
{
_set_se_translator( trans_func );
SEFunc();
}
catch( SE_Exception e )
{
printf( "Caught a __try exception with SE_Exception.\n" );
}
system("pause");
}
void SEFunc()
{
__try
{
int* buffer= new int[19];
buffer[19]=0;
printf("%d",buffer[19]);
delete buffer;
}
__finally
{
printf( "In finally\n" );
}
}
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
printf( "In trans_func.\n" );
throw SE_Exception();
}
trans_func will only be called in order to handle a structured exception.
But your code doesn't seem to trigger an SEH exception :
int* buffer= new int[19];
buffer[19]=0;
printf("%d",buffer[19]);
delete buffer;
Maybe you should try something a bit more brutal :
volatile int *pInt = 0x00000000;
*pInt = 20;
That example is directly taken from MSDN.
Related
I need to make sure the header I'm using is compiled with the /EHa compiler switch?
How can I do that?
inline bool CodeHasEHaSwitch()
{
bool dtorCalled = false;
struct CCheckEHaSwitch
{
CCheckEHaSwitch( bool& dtorCalled) : dtorCalled( dtorCalled ) {}
~CCheckEHaSwitch() { dtorCalled = true; }
bool& dtorCalled;
static void Win32ExceptionTranslator( unsigned int nExceptionCode,
EXCEPTION_POINTERS *pExceptionInfo )
{ throw nExceptionCode; }
};
_se_translator_function pfnPrevSeTranslator =
_set_se_translator( CCheckEHaSwitch::Win32ExceptionTranslator );
try
{
CCheckEHaSwitch test( dtorCalled );
*((int*)0) = 0; // generate access violation
}
catch (unsigned int)
{
}
_set_se_translator( pfnPrevSeTranslator );
return dtorCalled;
}
I have been trying to make a Windows application dump the callstack on the event of a crash (bad memory access or division by zero) or standard c++ exceptions.
I have build StackWalker and linked it into my application and compiled my application with /EHa.
#include "win/StackWalker.h"
extern int runapp(int argc, char **argv);
// The exception filter function:
LONG WINAPI ExpFilter(EXCEPTION_POINTERS* pExp, DWORD dwExpCode) {
StackWalker sw;
sw.ShowCallstack(GetCurrentThread(), pExp->ContextRecord);
return EXCEPTION_EXECUTE_HANDLER;
}
int main(int argc, char *argv[]) {
__try
{
return runapp(argc, argv);
}
__except (ExpFilter(GetExceptionInformation(), GetExceptionCode()))
{
}
}
The real program is started via runapp() since it is not possible to instantiate objects that require unwinding (destruction) directly inside a __try scope.
My problem is that nothing is caught when I force my program to crash using this code:
int *data1 = 0;
*data1 = 0;
In other words, it just crashes "normally"
Does anybody have a hint?
/EHa switch tells compiler that you want to handle SEH exceptions inside C++ try/catch block. In your code you use SEH exception handler instead. This is a working approach I am using:
dbgutils.h
#pragma once
#include <eh.h>
#include <windows.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <boost/optional.hpp>
#include "StackWalker.h"
class CSO3SEHException
{
public:
CSO3SEHException(unsigned int nCode, EXCEPTION_POINTERS* pEx);
std::string what();
std::string stack();
private:
std::string m_sWhat, m_sStack;
std::string seName(const unsigned int& nCode);
boost::optional<std::string> seInfo(unsigned int nCode, EXCEPTION_POINTERS* pEx);
void seStack(EXCEPTION_POINTERS* pEx);
void seExceptionInfo(unsigned int nCode, EXCEPTION_POINTERS* pEx);
};
class CCustomStackWalker : public StackWalker
{
public:
CCustomStackWalker(std::stringstream* ss);
protected:
virtual void OnOutput(LPCSTR szText);
private:
std::stringstream* m_sOut;
};
void _so3_seh_translate(unsigned int code, _EXCEPTION_POINTERS *ep);
void ReportSEHException(CSO3SEHException& ex);
dbgutils.cpp
#include "dbgutils.h"
CCustomStackWalker::CCustomStackWalker(std::stringstream* ss)
{
m_sOut = ss;
}
void CCustomStackWalker::OnOutput(LPCSTR szText)
{
size_t sLen = strlen(szText);
std::string s = std::string(szText, sLen);
(*m_sOut) << s << std::endl;
}
CSO3SEHException::CSO3SEHException(unsigned int nCode, EXCEPTION_POINTERS* pEx)
{
seExceptionInfo(nCode, pEx);
seStack(pEx);
}
std::string CSO3SEHException::what()
{
return(m_sWhat);
}
std::string CSO3SEHException::stack()
{
return(m_sStack);
}
std::string CSO3SEHException::seName(const unsigned int& nCode)
{
switch (nCode)
{
case EXCEPTION_ACCESS_VIOLATION: return ("Access Violation");
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return ("Range Check");
case EXCEPTION_BREAKPOINT: return ("Breakpoint");
case EXCEPTION_DATATYPE_MISALIGNMENT: return ("Datatype misaligment");
case EXCEPTION_ILLEGAL_INSTRUCTION: return ("Illegal instruction");
case EXCEPTION_INT_DIVIDE_BY_ZERO: return ("Divide by zero");
case EXCEPTION_INT_OVERFLOW: return ("Integer overflow");
case EXCEPTION_PRIV_INSTRUCTION: return ("Privileged instruction");
case EXCEPTION_STACK_OVERFLOW: return ("Stack overflow");
default: return("UNKNOWN EXCEPTION");
}
}
boost::optional<std::string> CSO3SEHException::seInfo(unsigned int nCode, EXCEPTION_POINTERS* pEx)
{
std::stringstream ss;
if (EXCEPTION_ACCESS_VIOLATION == nCode)
{
ss << (pEx->ExceptionRecord->ExceptionInformation[0] ? "write " : " read");
ss << std::hex << std::setfill('0');
ss << " of address 0x" << std::setw(2*sizeof(void*)) << (unsigned)pEx->ExceptionRecord->ExceptionInformation[1];
return(ss.str());
}
return(nullptr);
}
void CSO3SEHException::seStack(EXCEPTION_POINTERS* pEx)
{
std::stringstream ss;
CCustomStackWalker sw(&ss);
sw.ShowCallstack(GetCurrentThread(), pEx->ContextRecord);
m_sStack = ss.str();
}
void CSO3SEHException::seExceptionInfo(unsigned int nCode, EXCEPTION_POINTERS* pEx)
{
std::stringstream ss;
ss << seName(nCode);
ss << std::hex << std::setfill('0');
ss << " at 0x" << std::setw(2*sizeof(void*)) << pEx->ExceptionRecord->ExceptionAddress;
auto pSInfo = seInfo(nCode, pEx);
if (pSInfo)
ss << *pSInfo;
m_sWhat = ss.str();
}
void _so3_seh_translate(unsigned int code, _EXCEPTION_POINTERS *ep)
{
throw CSO3SEHException(code, ep);
}
void ReportSEHException(CSO3SEHException& ex)
{
std::string sError = ex.what();
std::string sStack = ex.stack();
//do some error reporting here
}
somewhere in your code:
//You have to call _set_se_translator in all threads
_set_se_translator(_so3_seh_translate);
try
{
//do something exception-prone
}
catch (CSO3SEHException & pSEH)
{
ReportSEHException(pSEH);
}
catch (std::exception& err)
{
//handle c++ exceptions
}
The following solution works cross-platform (with the inclusion of StackWalker). Unfortunately it only works across threads on posix systems.
If someone has a solution for catching crashes/exceptions in all threads on Windows please tell.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#ifdef WINDOWS_OS
#include <windows.h>
#include "StackWalker.h"
#include <DbgHelp.h>
#include <iostream>
void seg_handler(int sig)
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ ) {
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address );
}
free( symbol );
StackWalker sw;
sw.ShowCallstack(GetCurrentThread());
exit(1);
}
void std_handler( void ) {
seg_handler(1);
}
#else
#include <execinfo.h>
#include <unistd.h>
void seg_handler(int sig) {
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
void std_handler( void )
{
void *trace_elems[20];
int trace_elem_count(backtrace( trace_elems, 20 ));
char **stack_syms(backtrace_symbols( trace_elems, trace_elem_count ));
for ( int i = 0 ; i < trace_elem_count ; ++i )
{
std::cout << stack_syms[i] << "\n";
}
free( stack_syms );
exit(1);
}
#endif
int main(int argc, char *argv[]) {
signal(SIGSEGV, seg_handler);
std::set_terminate( std_handler );
// Main Program
// Crash
int *a = 0;
*a = 1;
}
I want to create a RAII wrapper around a file descriptor. As the object might be passed around threads, it really is a shared resource: this is why I made a first implementation by using a shared_ptr with a custom destructor.
struct file_descriptor
{
file_descriptor( const std::string & pathname, int flags )
:m_fd( initialize( pathname, flags ) )
{
}
file_descriptor( const int opened_fd )
:m_fd( initialize( opened_fd ) )
{
}
operator int() const { return *m_fd; }
private:
std::shared_ptr<int> initialize( const int opened_fd )
{
std::shared_ptr<int> ptr_to_fd;
try
{
int * shared_fd = new int;
ptr_to_fd = std::shared_ptr<int>( shared_fd, file_descriptor_closer() );
*shared_fd = opened_fd;
}
catch( std::bad_alloc & )
{
close( opened_fd );
throw;
}
return ptr_to_fd;
}
std::shared_ptr<int> initialize( const std::string & pathname, int flags )
{
const int fd = open( pathname.c_str(), flags );
if (fd < 0)
throw std::system_error( std::error_code(errno, std::system_category() ), "cannot create file descriptor" );
return initialize( fd );
}
std::shared_ptr<int> m_fd;
};
The custom destructor, is pretty simple:
struct file_descriptor_closer
{
void operator()(int * const fd) noexcept { if (fd) close(*fd); delete fd; }
};
Now I find the design horrible, namely because of the "new int". I thought about making a custom allocator to point to an already-allocated block, but that seems overkill. Do you guys have suggestion to simplify this?
IMHO, you're mixing responsibilities. Let your RAII class deal with the opening and closing of the file descriptor. Let some other class deal with the lifetime question of your RAII class. As you have it now, the user of your file_descriptor class would need to know that it is using a shared_ptr internally. On first glance, if I were to share a file_descriptor between threads, I'd be making a shared_ptr<file_descriptor> of my own to counter the problem that I don't really know that internally it's already doing one.
use some gentle violence:
struct file_descriptor_closer
{
void operator()(void* fd) noexcept { if (fd) close(reinterpret_cast< int >(fd)); }
};
struct file_descriptor
{
file_descriptor( const std::string & pathname, int flags )
:m_fd( initialize( pathname, flags ) )
{
}
file_descriptor( const int opened_fd )
:m_fd( initialize( opened_fd ) )
{
}
operator int() const { return reinterpret_cast< int >(m_fd.get()); }
private:
std::shared_ptr<void> initialize( const int opened_fd )
{
try
{
return std::shared_ptr< void >( reinterpret_cast< void* >( opened_fd ), file_descriptor_closer() );
}
catch( std::bad_alloc & )
{
close( opened_fd );
throw;
}
}
std::shared_ptr<void> initialize( const std::string & pathname, int flags )
{
const int fd = open( pathname.c_str(), flags );
if (fd < 0)
throw std::system_error( std::error_code(errno, std::system_category() ), "cannot create file descriptor" );
return initialize( fd );
}
std::shared_ptr<void> m_fd;
};
Why not create your own container? What about something like: http://ideone.com/m3kmaJ or with static counter: http://ideone.com/Gs4Kb7
#include <iostream>
#include <sys/stat.h>
#include <fcntl.h>
#include <thread>
#include <memory>
#include <unistd.h>
#include <atomic>
class FD
{
private:
int fd;
static int count;
public:
FD(const char* FilePath, int flags) : fd(open(FilePath, flags)) {++FD::count;}
FD(const FD& other) : fd(other.fd) {++FD::count;}
FD(FD&& other) : fd(other.fd) { other.fd = -1; }
~FD()
{
FD::count -= 1;
if (FD::count == 0)
{
std::cout<<"Destroyed\n";
if (is_open())
close(fd);
}
}
bool is_open() {return fd != -1;}
FD* operator &() {return nullptr;}
operator int() {return fd;}
FD& operator = (FD other)
{
fd = other.fd;
FD::count += 1;
return *this;
}
FD& operator = (FD&& other)
{
fd = other.fd;
other.fd = -1;
return *this;
}
};
int FD::count = 0;
int main()
{
FD fd = FD("Unicode.cpp", O_RDONLY);
FD copy = fd;
FD cpy = FD(copy);
return 0;
}
The following code compiles and runs on standard linux:
#include <iostream>
#include <pthread.h>
using namespace std;
class Foo
{
public:
Foo();
void go_thread();
void stop_thread();
private:
static void* worker( void* param );
pthread_t m_pt;
};
Foo::Foo()
{
m_pt = 0;
}
void Foo::go_thread()
{
int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );
if( success == 0 )
{
cout << "thread started" << endl;
}
}
void Foo::stop_thread()
{
int success = pthread_join( m_pt, NULL );
if( success == 0 )
{
cout << "thread stopped" << endl;
}
}
void* Foo::worker( void* p )
{
cout << "thread running" << endl;
return 0;
}
int main()
{
Foo f;
f.go_thread();
f.stop_thread();
return 0;
}
and produces the following output:
$ ./a.out
thread started
thread running
thread stopped
$
This code also builds with the Android NDK (r5b). However, when I adb push the resulting executable to a device and run it, I get a SIGSEGV before main() even runs. I've isolated the issue down to pthread_create() It seems the mere existence of this call in my code, never mind execution, causes my prog to seg fault. Any ideas?
It may not be this but try making the function called by pthread create a normal c-function (i.e. declare it as extern "C") not a static member function:
This is because technically the calling convention for static members may be different from the C calling convention that is used by the C-library pthread (though a lot of the times they are the same (which is why it works on your linux box) in my opinion it is not worth the porting risk).
extern "C" void* start_the_thread(void*);
void* start_the_thread(void* data)
{
Foo* theObject = static_cast<Foo*>(data);
// In Java if your Foo had been derived from Runable
// This is s where theObject->run() would have been called.
return Foo::worker(data);
}
int success = pthread_create( &m_pt, NULL, start_the_thread, static_cast<void*>(this)
The issue seems to be combining iostream with pthread. I went through and replaced all couts with printf()s, removed the using clause, and removed the iostream header. The code compiled and ran with no issue on the device. I wonder if this is something Google should be made aware of?
The final (working) code looks like:
#include <pthread.h>
#include <stdio.h>
class Foo
{
public:
Foo();
void go_thread();
void stop_thread();
private:
static void* worker( void* param );
pthread_t m_pt;
};
Foo::Foo()
{
m_pt = 0;
}
void Foo::go_thread()
{
int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );
if( success == 0 )
{
printf( "thread started\n" );
}
}
void Foo::stop_thread()
{
int success = pthread_join( m_pt, NULL );
if( success == 0 )
{
printf( "thread stopped\n" );
}
}
void* Foo::worker( void* p )
{
printf( "thread running\n" );
return 0;
}
int main()
{
Foo f;
f.go_thread();
f.stop_thread();
return 0;
}
Hey everyone, considering the following code (compiled with g++ -lpthread thread_test.cpp) how can I know what number thread I am in from inside "thread_function"? And let me know if you have any other suggestions.
Thanks!
thread_test.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
class A {
public:
A();
void run();
private:
static void* thread_function( void *ptr );
pthread_t m_thread1, m_thread2;
static int m_global;
};
int A::m_global = 0;
A::A() {
int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function, this );
int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function, this );
}
void A::run() {
while ( 1 ) {
printf( "parent incrementing...\n" );
m_global++;
sleep( 2 );
}
}
void* A::thread_function( void *ptr ) {
printf( "I'm thread ?\n" );
while ( 1 ) {
printf("thread global: %d\n", m_global );
sleep( 1 );
}
}
int main() {
A a;
a.run();
return 0;
}
You can use pthread_self() function.
Well i figured out I could do this, but I'm not sure if making the pthread_t variables static is the best thing to do. Opinions?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
class A {
public:
A();
void run();
private:
static void* thread_function( void *ptr );
static pthread_t m_thread1, m_thread2;
static int m_global;
};
int A::m_global = 0;
pthread_t A::m_thread1 = 0;
pthread_t A::m_thread2 = 0;
A::A() {
int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function, this );
int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function, this );
}
void A::run() {
while ( 1 ) {
printf( "parent incrementing...\n" );
m_global++;
sleep( 2 );
}
}
void* A::thread_function( void *ptr ) {
int thread_num = 0;
if ( pthread_self() == m_thread1 ) {
thread_num = 1;
} else {
thread_num = 2;
}
printf( "I'm thread %d\n", thread_num );
while ( 1 ) {
printf("thread %d global: %d\n", thread_num, m_global );
sleep( 1 );
}
}
int main() {
A a;
a.run();
return 0;
}
The correct answer depends heavily on why you need this information. If the two threads are doing different things, why do they have the same start function?
One simple fix is this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
class A {
public:
A();
void run();
private:
static void* thread_function( void *ptr, int which );
static void* thread_function_1( void *ptr );
static void* thread_function_2( void *ptr );
pthread_t m_thread1, m_thread2;
static int m_global;
};
int A::m_global = 0;
A::A() {
int ret1 = pthread_create( &m_thread1, NULL, &A::thread_function_1, this );
int ret2 = pthread_create( &m_thread2, NULL, &A::thread_function_2, this );
}
void A::run() {
while ( 1 ) {
printf( "parent incrementing...\n" );
m_global++;
sleep( 2 );
}
}
void* A::thread_function_1( void *ptr ) { thread_function(ptr, 1); }
void* A::thread_function_2( void *ptr ) { thread_function(ptr, 2); }
void* A::thread_function( void *ptr, int which ) {
printf( "I'm thread %d\n", which );
while ( 1 ) {
printf("thread global: %d\n", m_global );
sleep( 1 );
}
}
int main() {
A a;
a.run();
return 0;
}
If you have more than 2 threads, you can use another approach. Create a structure that holds all the information the thread needs, including the this pointer and which thread it is. Allocate a structure of that type, stuff it with everything the thread needs and pass that to the thread through the pthread_create function instead of just the this pointer.