Exemplo n.º 1
0
/*
 * Hook into the qWarning/qFatal mechanism so that we can channel messages
 * from libpng to the user.
 *
 * Some JPL WMS images tend to overload the libpng 1.2.2 implementation
 * somehow (especially when zoomed in)
 * and it would be useful for the user to know why their picture turned up blank
 *
 * Based on qInstallMsgHandler example code in the Qt documentation.
 *
 */
void myMessageOutput( QtMsgType type, const char *msg )
{
  switch ( type )
  {
    case QtDebugMsg:
      myPrint( "%s\n", msg );
      if ( strncmp( msg, "Backtrace", 9 ) == 0 )
        dumpBacktrace( atoi( msg + 9 ) );
      break;
    case QtCriticalMsg:
      myPrint( "Critical: %s\n", msg );
      break;
    case QtWarningMsg:
      myPrint( "Warning: %s\n", msg );

#ifdef QGISDEBUG
      // Print all warnings except setNamedColor.
      // Only seems to happen on windows
      if ( 0 != strncmp( msg, "QColor::setNamedColor: Unknown color name 'param", 48 ) )
      {
        // TODO: Verify this code in action.
        dumpBacktrace( 20 );
        QgsMessageLog::logMessage( msg, "Qt" );
      }
#endif

      // TODO: Verify this code in action.
      if ( 0 == strncmp( msg, "libpng error:", 13 ) )
      {
        // Let the user know
        QgsMessageLog::logMessage( msg, "libpng" );
      }

      break;
    case QtFatalMsg:
    {
      myPrint( "Fatal: %s\n", msg );
#if (defined(linux) && !defined(ANDROID)) || defined(__FreeBSD__)
      qgisCrash( -1 );
#else
      dumpBacktrace( 256 );
      abort();                    // deliberately dump core
#endif
    }


#if QT_VERSION >= 0x050500
    case QtInfoMsg:
      myPrint( "Info: %s\n", msg );
      break;
#endif

  }
}
Exemplo n.º 2
0
//----------------------------------------------------------------------------//
Exception::Exception(const String& message, const String& name,
                     const String& filename, int line, const String& function) :
    d_message(message),
    d_name(name),
    d_filename(filename),
    d_line(line),
    d_function(function),
    d_what(name + " in function '" + function +
           "' (" + filename + ":" + PropertyHelper<int>::toString(line) + ") : " +
           message)
{
    // Log exception if possible
    if (Logger* const logger = Logger::getSingletonPtr())
    {
        logger->logEvent(d_what, Errors);
        dumpBacktrace(64);
    }

    if (d_stdErrEnabled)
    {
        // output to stderr unless it's explicitly disabled
        // nobody seems to look in their log file!
        std::cerr << what() << std::endl;
    }
}
Exemplo n.º 3
0
void handleCrash(int signalNumber, siginfo_t *sigInfo, void *context) {
    static volatile sig_atomic_t fatal_error_in_progress = 0;
    if (fatal_error_in_progress) //Stop a signal loop.
        _exit(1);
    fatal_error_in_progress = 1;

    char *j;
    char *signumber = strdup(sys_signame[signalNumber]);
    upcase(signumber);
    asprintf(&j, "Crash Signal: %s, crashed on: %li, UID: %ld\n", signumber, (long) sigInfo->si_addr, (long) sigInfo->si_uid);  //%x prints out the faulty memory address in hex
    LOGE("%s", j);

    const size_t max = 30;
    void *buffer[max];
    std::ostringstream oss;

    bool encodingCrash = dumpBacktrace(oss, buffer, captureBacktrace(buffer, max));

    LOGE("%s", oss.str().c_str());
    if (encodingCrash) {
        pthread_t *id = (pthread_t *) malloc(sizeof(pthread_t));
        pthread_create(id, NULL, notifyThread, NULL);
        pthread_join(*id, NULL);
    }
    call_old_signal_handler(signalNumber, sigInfo, context);
}
Exemplo n.º 4
0
// The signal handler. If this function is called, it means shit has probably collided with some sort of device one might use to keep oneself cool.
// This is the generic part of the code that will be called after platform specific handling is finished.
void handleCrash(CrashData crash)
{
#ifdef Q_OS_UNIX
	fprintf(stderr, "Fatal error! Received signal %d\n", crash.signal);
#endif

	time_t unixTime = 0;		// Unix timestamp. Used to give our crash dumps "unique" names.

	char dumpFileName[DUMPF_NAME_LEN]; // The name of the file we're dumping to.
	int dumpFile; // File descriptor for our dump file.

	// Determine what our dump file should be called.
	// We'll just call it "mmc-crash-<unixtime>.dump"
	// First, check the time.
	time(&unixTime);

	// Now we get to do some !!FUN!! hackery to ensure we don't use the stack when we convert
	// the timestamp from an int to a string. To do this, we just allocate a fixed size array
	// of chars on the stack, and sprintf into it. We know the timestamp won't ever be longer
	// than a certain number of digits, so this should work just fine.
	// sprintf doesn't support writing signed values as hex, so this breaks on negative timestamps.
	// It really shouldn't matter, though...
	sprintf(dumpFileName, DUMPF_NAME_FMT, unixTime);

	// Now, we need to open the file.
	// Fail if it already exists. This should never happen.
	dumpFile = open(dumpFileName, O_WRONLY | O_CREAT | O_TRUNC, 0644);


	if (dumpFile >= 0)
	{
		// If we opened the dump file successfully.
		// Dump everything we can and GTFO.
		fprintf(stderr, "Dumping crash report to %s\n", dumpFileName);

		// Dump misc info
		dprintf(dumpFile, "Unix Time: %d\n", unixTime);
		dumpErrorInfo(dumpFile, crash);
		dumpMiscInfo(dumpFile);

		dprintf(dumpFile, "\n");

		dumpSysInfo(dumpFile);

		dprintf(dumpFile, "\n");

		dumpBacktrace(dumpFile, crash);

		dprintf(dumpFile, "\n");

		// DIE DIE DIE!
		exit(1);
	}
	else
	{
		fprintf(stderr, "Failed to open dump file %s to write crash info (ERRNO: %d)\n", dumpFileName, errno);
		exit(2);
	}
}
Exemplo n.º 5
0
void printStackTrace(unsigned int max_frames)
{
    void* buffer[max_frames];
    std::ostringstream oss;

    dumpBacktrace(oss, buffer, captureBacktrace(buffer, max_frames));

    __android_log_print(ANDROID_LOG_DEBUG, TAG, "%s", oss.str().c_str());
}
Exemplo n.º 6
0
void qgisCrash( int signal )
{
  fprintf( stderr, "QGIS died on signal %d", signal );

  if ( access( "/usr/bin/gdb", X_OK ) == 0 )
  {
    // take full stacktrace using gdb
    // http://stackoverflow.com/questions/3151779/how-its-better-to-invoke-gdb-from-program-to-print-its-stacktrace
    // unfortunately, this is not so simple. the proper method is way more OS-specific
    // than this code would suggest, see http://stackoverflow.com/a/1024937

    char exename[512];
#if defined(__FreeBSD__)
    int len = readlink( "/proc/curproc/file", exename, sizeof( exename ) - 1 );
#else
    int len = readlink( "/proc/self/exe", exename, sizeof( exename ) - 1 );
#endif
    if ( len < 0 )
    {
      myPrint( "Could not read link (%d:%s)\n", errno, strerror( errno ) );
    }
    else
    {
      exename[ len ] = 0;

      char pidstr[32];
      snprintf( pidstr, sizeof pidstr, "--pid=%d", getpid() );

      int gdbpid = fork();
      if ( gdbpid == 0 )
      {
        // attach, backtrace and continue
        execl( "/usr/bin/gdb", "gdb", "-q", "-batch", "-n", pidstr, "-ex", "thread", "-ex", "bt full", exename, NULL );
        perror( "cannot exec gdb" );
        exit( 1 );
      }
      else if ( gdbpid >= 0 )
      {
        int status;
        waitpid( gdbpid, &status, 0 );
        myPrint( "gdb returned %d\n", status );
      }
      else
      {
        myPrint( "Cannot fork (%d:%s)\n", errno, strerror( errno ) );
        dumpBacktrace( 256 );
      }
    }
  }

  abort();
}
Exemplo n.º 7
0
void avgAssert(bool b, const char * pszFile, int line, const char * pszReason)
{
    if (!b) {
        string sDummy;
        static bool bBreak = getEnv("AVG_BREAK_ON_ASSERT", sDummy);
        if (bBreak) {
            debugBreak();
        } else {
            stringstream ss;
            ss << "Assertion failed in " << pszFile << ": " << line << endl;
            if (pszReason) {
                ss << "Reason: " << pszReason << endl;
            }
            dumpBacktrace();
            throw(Exception(AVG_ERR_ASSERT_FAILED, ss.str()));
        }
    }
}
Exemplo n.º 8
0
void Ref::release()
{
    CCASSERT(_referenceCount > 0, "reference count should be greater than 0");
    if(_referenceCount <= 0){
        return;
    }
    --_referenceCount;
    
    auto poolManager = PoolManager::getInstance();
    if (_isInAutoPool&&poolManager->isClearing()) {
        _isInAutoPool = false;
    }

    if (_referenceCount == 0)
    {
        //auto poolManager = PoolManager::getInstance();
        
        if (_isInAutoPool&&!poolManager->isClearing() )//&& poolManager->isObjectInPools(this))
        {
            poolManager->removeObject(this);
        }
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
//        auto poolManager = PoolManager::getInstance();
//        if (!poolManager->getCurrentPool()->isClearing() && poolManager->isObjectInPools(this))
//        {
//        }
            // Trigger an assert if the reference count is 0 but the Ref is still in autorelease pool.
            // This happens when 'autorelease/release' were not used in pairs with 'new/retain'.
            //
            // Wrong usage (1):
            //
            // auto obj = Node::create();   // Ref = 1, but it's an autorelease Ref which means it was in the autorelease pool.
            // obj->autorelease();   // Wrong: If you wish to invoke autorelease several times, you should retain `obj` first.
            //
            // Wrong usage (2):
            //
            // auto obj = Node::create();
            // obj->release();   // Wrong: obj is an autorelease Ref, it will be released when clearing current pool.
            //
            // Correct usage (1):
            //
            // auto obj = Node::create();
            //                     |-   new Node();     // `new` is the pair of the `autorelease` of next line
            //                     |-   autorelease();  // The pair of `new Node`.
            //
            // obj->retain();
            // obj->autorelease();  // This `autorelease` is the pair of `retain` of previous line.
            //
            // Correct usage (2):
            //
            // auto obj = Node::create();
            // obj->retain();
            // obj->release();   // This `release` is the pair of `retain` of previous line.
//            CCASSERT(false, "The reference shouldn't be 0 because it is still in autorelease pool.");
//        }
#endif

#if CC_REF_LEAK_DETECTION
        untrackRef(this);
#endif
        if ( g_performanceCrashSwitch && _isInAutoPool && !poolManager->isClearing() )
        {
#ifdef CC_ENABLE_BACKTRACE
            const size_t max = 30;
            void* buffer[max];
            dumpBacktrace( buffer, captureBacktrace(buffer, max));
#endif
            
            int *pTest = NULL;
            *pTest =  123456;
        }
        
        delete this;
    }
}