SilentMLscribe

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
#include "TEnv.h"
#include "TSystem.h"
#include "TEveManager.h"
#include "TRint.h"
#include "TApplication.h"
#include "TSysEvtHandler.h"
#include "Getline.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <memory>
#include <csignal>

#include "Fireworks/Core/interface/CmsShowMain.h"
#include "Fireworks/Core/interface/fwPaths.h"
/* NOTE: This is a short term work around until FWLite can properly handle the MessageLogger
 */
#include "FWCore/MessageLogger/interface/AbstractMLscribe.h"
#include "FWCore/MessageLogger/interface/ErrorObj.h"
#include "FWCore/MessageLogger/interface/MessageLoggerQ.h"
#include "FWCore/MessageLogger/interface/MessageDrop.h"

namespace {
  class SilentMLscribe : public edm::service::AbstractMLscribe {
  public:
    SilentMLscribe() {}

    // ---------- member functions ---------------------------

    void runCommand(edm::MessageLoggerQ::OpCode opcode, void* operand) override;

    SilentMLscribe(const SilentMLscribe&) = delete;  // stop default

    const SilentMLscribe& operator=(const SilentMLscribe&) = delete;  // stop default

    // ---------- member data --------------------------------
  };

  void SilentMLscribe::runCommand(edm::MessageLoggerQ::OpCode opcode, void* operand) {
    //even though we don't print, have to clean up memory
    switch (opcode) {
      case edm::MessageLoggerQ::LOG_A_MESSAGE: {
        edm::ErrorObj* errorobj_p = static_cast<edm::ErrorObj*>(operand);
        //std::cerr<<errorobj_p->xid().severity.getInputStr()<<" "<<errorobj_p->xid().id<<" -----------------------"<<std::endl;
        //std::cerr <<errorobj_p->fullText()<<std::endl;
        delete errorobj_p;
        break;
      }
      case edm::MessageLoggerQ::JOBMODE:
      case edm::MessageLoggerQ::GROUP_STATS: {
        std::string* string_p = static_cast<std::string*>(operand);
        delete string_p;
        break;
      }
      default:
        break;
    }
  }

}  // namespace

namespace {
  void signal_handler_wrapper(int sid, siginfo_t* sinfo, void* sctx) {
#if defined(R__LINUX)
    std::cerr << "Program received signal ID = " << sid << std::endl;
    std::cerr << "Printing stack trace ... " << std::endl;

    TString gdbCommand("scripts/gdb-backtrace.sh");
    fireworks::setPath(gdbCommand);
    gdbCommand += " ";

    gdbCommand += gSystem->GetPid();

    gSystem->Exec(gdbCommand.Data());
    gSystem->Exit(sid);
    Getlinem(kCleanUp, nullptr);
#endif
  }
}  // namespace

void run_app(TApplication& app, int argc, char** argv) {
  //Remove when FWLite handles the MessageLogger
  edm::MessageLoggerQ::setMLscribe_ptr(
      std::shared_ptr<edm::service::AbstractMLscribe>(std::make_shared<SilentMLscribe>()));
  edm::MessageDrop::instance()->messageLoggerScribeIsRunning = edm::MLSCRIBE_RUNNING_INDICATOR;
  //---------------------
  std::unique_ptr<CmsShowMain> pMain(new CmsShowMain(argc, argv));

  // Avoid haing root handling various associated to an error and install
  // back the default ones.
  gSystem->ResetSignal(kSigBus);
  gSystem->ResetSignal(kSigSegmentationViolation);
  gSystem->ResetSignal(kSigIllegalInstruction);
  gSystem->ResetSignal(kSigSystem);
  gSystem->ResetSignal(kSigPipe);
  gSystem->ResetSignal(kSigFloatingException);

  struct sigaction sac;
  sac.sa_sigaction = signal_handler_wrapper;
  sigemptyset(&sac.sa_mask);
  sac.sa_flags = SA_SIGINFO;
  sigaction(SIGILL, &sac, nullptr);
  sigaction(SIGSEGV, &sac, nullptr);
  sigaction(SIGBUS, &sac, nullptr);
  sigaction(SIGFPE, &sac, nullptr);

  app.Run();
  pMain.reset();

  TEveManager::Terminate();
  app.Terminate();

  //Remove when FWLite handled the MessageLogger
  edm::MessageLoggerQ::MLqEND();
}

int main(int argc, char** argv) {
  const char* dummyArgvArray[] = {"cmsShow"};
  char** dummyArgv = const_cast<char**>(dummyArgvArray);
  int dummyArgc = 1;
  gEnv->SetValue("Gui.BackgroundColor", "#9f9f9f");

  // print version
  TString infoText;
  if (gSystem->Getenv("CMSSW_VERSION")) {
    infoText = gSystem->Getenv("CMSSW_VERSION");
  } else {
    TString infoFileName("data/version.txt");
    fireworks::setPath(infoFileName);
    std::ifstream infoFile(infoFileName);
    infoText.ReadLine(infoFile);
    infoFile.close();
  }
  printf("Starting cmsShow, version %s.\n", infoText.Data());
  fflush(stdout);

  // check root interactive promp
  bool isri = false;
  for (Int_t i = 0; i < argc; i++) {
    if (strncmp(argv[i], "-r", 2) == 0 || strncmp(argv[i], "--root", 6) == 0) {
      isri = true;
    }
  }

  try {
    if (isri) {
      std::cerr << "" << std::endl;
      std::cerr << "WARNING:You are running cmsShow with ROOT prompt enabled." << std::endl;
      std::cerr << "If you encounter an issue you suspect to be a bug in     " << std::endl;
      std::cerr << "cmsShow, please re-run without this option and try to    " << std::endl;
      std::cerr << "reproduce it before submitting a bug-report.             " << std::endl;
      std::cerr << "" << std::endl;

      TRint app("cmsShow", &dummyArgc, dummyArgv);
      run_app(app, argc, argv);
    } else {
      TApplication app("cmsShow", &dummyArgc, dummyArgv);
      run_app(app, argc, argv);
    }
  } catch (std::exception& iException) {
    std::cerr << "CmsShow unhandled exception " << iException.what() << std::endl;
    return 1;
  }

  return 0;
}