void Docbook2XhtmlGeneratorJob::run()
{
  UMLDoc* umlDoc = UMLApp::app()->document();
  xsltStylesheetPtr cur = NULL;
  xmlDocPtr doc, res;

  const char *params[16 + 1];
  int nbparams = 0;
  params[nbparams] = NULL;

  umlDoc->writeToStatusBar(i18n("Exporting to XHTML..."));

  QString xsltFileName(KGlobal::dirs()->findResource("appdata", QLatin1String("docbook2xhtml.xsl")));
  uDebug() << "XSLT file is'" << xsltFileName << "'";
  QFile xsltFile(xsltFileName);
  xsltFile.open(QIODevice::ReadOnly);
  QString xslt = QString::fromLatin1(xsltFile.readAll());
  uDebug() << "XSLT is'" << xslt << "'";
  xsltFile.close();

  QString localXsl = KGlobal::dirs()->findResource("data", QLatin1String("ksgmltools2/docbook/xsl/html/docbook.xsl"));
  uDebug() << "Local xsl is'" << localXsl << "'";
  if (!localXsl.isEmpty())
  {
    localXsl = QLatin1String("href=\"file://") + localXsl + QLatin1String("\"");
    xslt.replace(QRegExp(QLatin1String("href=\"http://[^\"]*\"")), localXsl);
  }
  KTemporaryFile tmpXsl;
  tmpXsl.setAutoRemove(false);
  tmpXsl.open();
  QTextStream str (&tmpXsl);
  str << xslt;
  str.flush();

  xmlSubstituteEntitiesDefault(1);
  xmlLoadExtDtdDefaultValue = 1;
  uDebug() << "Parsing stylesheet " << tmpXsl.fileName();
  cur = xsltParseStylesheetFile((const xmlChar *)tmpXsl.fileName().toLatin1().constData());
  uDebug() << "Parsing file " << m_docbookUrl.path();
  doc = xmlParseFile((const char*)(m_docbookUrl.path().toUtf8()));
  uDebug() << "Applying stylesheet ";
  res = xsltApplyStylesheet(cur, doc, params);

  KTemporaryFile tmpXhtml;
  tmpXhtml.setAutoRemove(false);
  tmpXhtml.open();

  uDebug() << "Writing HTML result to temp file: " << tmpXhtml.fileName();
  xsltSaveResultToFd(tmpXhtml.handle(), res, cur);

  xsltFreeStylesheet(cur);
  xmlFreeDoc(res);
  xmlFreeDoc(doc);

  xsltCleanupGlobals();
  xmlCleanupParser();

  emit xhtmlGenerated(tmpXhtml.fileName());
}
	void testMMap()
	{
		KTemporaryFile tmp;
		QVERIFY(tmp.open());
		int fd = tmp.handle();
		try
		{
			TruncateFile(fd, 4096, true);
		}
		catch (bt::Error & err)
		{
			QString msg = QString("Exception thrown: %s").arg(err.toString());
			QFAIL(msg.toLocal8Bit());
		}
		
		
		char* ptr = (char*)mmap(0, 4096, PROT_WRITE, MAP_SHARED, fd, 0);
		QVERIFY(ptr);
		
		// First try a write which should not fail
		try
		{
			BUS_ERROR_WPROTECT();
			memcpy(ptr,"Testing",7);
		}
		catch (bt::BusError & e)
		{
			QString msg = QString("Caught signal: %s").arg(e.toString());
			QFAIL(msg.toLocal8Bit());
		}
		
		// Lets try one which should fail
		try
		{
			BUS_ERROR_WPROTECT();
			TruncateFile(fd, 0, true);
			memcpy(ptr,"Testing",7);
			QFAIL("Didn't catch SIGBUS");
		}
		catch (bt::BusError & e)
		{
			Out(SYS_GEN|LOG_DEBUG) << QString("Caught signal: %1").arg(e.toString()) << endl;
		}
	}
Beispiel #3
0
void
Crash::crashHandler(int /*signal*/)
{
#ifndef Q_WS_WIN 
    // we need to fork to be able to get a
    // semi-decent bt - I dunno why
    const pid_t pid = ::fork();

    if (pid <= 0) {
        // we are the child process (the result of the fork)
//            debug() << "amaroK is crashing...\n";

        QString subject = "[basket-crash] " VERSION " ";
        QString body = i18n(
                           "%1 has crashed! We're sorry about this.\n"
                           "\n"
                           "But, all is not lost! You could potentially help us fix the crash. "
                           "Information describing the crash is below, so just click send, "
                           "or if you have time, write a brief description of how the crash happened first.\n\n"
                           "Many thanks.", KGlobal::mainComponent().aboutData()->programName()) + "\n\n";
        body += "\n\n\n\n\n\n" + i18n(
                    "The information below is to help the developers identify the problem, "
                    "please do not modify it.") + "\n\n\n\n";


        body += "======== DEBUG INFORMATION  =======\n"
                "Version:    " VERSION "\n"
                "CC version: " __VERSION__ "\n" //assuming we're using GCC
                "KDElibs:    " KDE_VERSION_STRING "\n"
                ;//                    "TagLib:     %2.%3.%4\n";

        /*            body = body
                            .arg( TAGLIB_MAJOR_VERSION )
                            .arg( TAGLIB_MINOR_VERSION )
                            .arg( TAGLIB_PATCH_VERSION );*/

#ifdef NDEBUG
        body += "NDEBUG:     true";
#endif
        body += "\n";

        /// obtain the backtrace with gdb

	KTemporaryFile temp;
	temp.open();	
        temp.setAutoRemove(true);

        const int handle = temp.handle();

//             QCString gdb_command_string =
//                     "file amarokapp\n"
//                     "attach " + QCString().setNum( ::getppid() ) + "\n"
//                     "bt\n" "echo \\n\n"
//                     "thread apply all bt\n";

        const QByteArray gdb_batch =
            "bt\n"
            "echo \\n\\n\n"
            "bt full\n"
            "echo \\n\\n\n"
            "echo ==== (gdb) thread apply all bt ====\\n\n"
            "thread apply all bt\n";

        ::write(handle, gdb_batch, gdb_batch.length());
        ::fsync(handle);

        // so we can read stderr too
        ::dup2(fileno(stdout), fileno(stderr));

        QByteArray gdb;
        gdb  = "gdb --nw -n --batch -x ";
        gdb += temp.fileName().toLatin1();
        gdb += " ";
	gdb += KCmdLineArgs::qtArgv()[0];
	gdb += " ";
        gdb += QByteArray().setNum(::getppid());

 
       QString bt = runCommand(gdb);

        /// clean up
        bt.remove("(no debugging symbols found)...");
        bt.remove("(no debugging symbols found)\n");
        bt.replace(QRegExp("\n{2,}"), "\n");   //clean up multiple \n characters
        bt.trimmed();

        /// analyze usefulness
        bool useful = true;
        const QString fileCommandOutput = runCommand("file `which basket`");

        if (fileCommandOutput.indexOf("not stripped") == -1)
            subject += "[___stripped]"; //same length as below
        else
            subject += "[NOTstripped]";

        if (!bt.isEmpty()) {
            const int invalidFrames = bt.count(QRegExp("\n#[0-9]+\\s+0x[0-9A-Fa-f]+ in \\?\\?"));
            const int validFrames = bt.count(QRegExp("\n#[0-9]+\\s+0x[0-9A-Fa-f]+ in [^?]"));
            const int totalFrames = invalidFrames + validFrames;

            if (totalFrames > 0) {
                const double validity = double(validFrames) / totalFrames;
                subject += QString("[validity: %1]").arg(validity, 0, 'f', 2);
                if (validity <= 0.5) useful = false;
            }
            subject += QString("[frames: %1]").arg(totalFrames, 3 /*padding*/);

            if (bt.indexOf(QRegExp(" at \\w*\\.cpp:\\d+\n")) != -1)
                subject += "[line numbers]";
        } else
            useful = false;

//            subject += QString("[%1]").arg( AmarokConfig::soundSystem().remove( QRegExp("-?engine") ) );

//            debug() << subject << endl;

        //TODO -fomit-frame-pointer buggers up the backtrace, so detect it
        //TODO -O optimization can rearrange execution and stuff so show a warning for the developer
        //TODO pass the CXXFLAGS used with the email

        if (useful) {
            body += "==== file `which basket` ==========\n";
            body += fileCommandOutput + "\n";
            body += "==== (gdb) bt =====================\n";
            body += bt;//+ "\n\n";
//                body += "==== kBacktrace() ================\n";
//                body += kBacktrace();

            //TODO startup notification
            KToolInvocation::invokeMailer(
                /*to*/          "*****@*****.**",
                /*cc*/          QString(),
                /*bcc*/         QString(),
                /*subject*/     subject,
                /*body*/        body,
                /*messageFile*/ QString(),
                /*attachURLs*/  QStringList(),
                /*startup_id*/  "");
        } else {
            kDebug() << "\n" + i18n("%1 has crashed! We're sorry about this.\n\n"
                                    "But, all is not lost! Perhaps an upgrade is already available "
                                    "which fixes the problem. Please check your distribution's software repository.",
                                    KGlobal::mainComponent().aboutData()->programName());
        }

        //_exit() exits immediately, otherwise this
        //function is called repeatedly ad finitum
        ::_exit(255);
    }

    else {
        // we are the process that crashed
        
        ::alarm(0);

        // wait for child to exit
        ::waitpid(pid, NULL, 0);
        ::_exit(253);
    }
#endif //#ifndef Q_WS_WIN 
}