sc_report_handler.cc revision 13312
112852Sgabeblack@google.com/* 212852Sgabeblack@google.com * Copyright 2018 Google, Inc. 312852Sgabeblack@google.com * 412852Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512852Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612852Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812852Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012852Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112852Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212852Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312852Sgabeblack@google.com * this software without specific prior written permission. 1412852Sgabeblack@google.com * 1512852Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612852Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712852Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812852Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912852Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012852Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112852Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212852Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312852Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412852Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512852Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612852Sgabeblack@google.com * 2712852Sgabeblack@google.com * Authors: Gabe Black 2812852Sgabeblack@google.com */ 2912852Sgabeblack@google.com 3012997Sgabeblack@google.com#include <fstream> 3112997Sgabeblack@google.com#include <map> 3212997Sgabeblack@google.com#include <sstream> 3312997Sgabeblack@google.com#include <string> 3412997Sgabeblack@google.com 3512852Sgabeblack@google.com#include "base/logging.hh" 3612997Sgabeblack@google.com#include "systemc/core/process.hh" 3712997Sgabeblack@google.com#include "systemc/core/scheduler.hh" 3812997Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 3912852Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh" 4013312Sgabeblack@google.com#include "systemc/utils/report.hh" 4112852Sgabeblack@google.com 4212852Sgabeblack@google.comnamespace sc_core 4312852Sgabeblack@google.com{ 4412852Sgabeblack@google.com 4512997Sgabeblack@google.comnamespace 4612997Sgabeblack@google.com{ 4712997Sgabeblack@google.com 4812997Sgabeblack@google.comstd::unique_ptr<std::string> logFileName; 4912997Sgabeblack@google.comstd::unique_ptr<std::ofstream> logFile; 5012997Sgabeblack@google.com 5112997Sgabeblack@google.com} // anonymous namespace 5212997Sgabeblack@google.com 5312852Sgabeblack@google.comvoid 5412997Sgabeblack@google.comsc_report_handler::report(sc_severity severity, const char *msg_type, 5512997Sgabeblack@google.com const char *msg, const char *file, int line) 5612852Sgabeblack@google.com{ 5712997Sgabeblack@google.com report(severity, msg_type, msg, SC_MEDIUM, file, line); 5812852Sgabeblack@google.com} 5912852Sgabeblack@google.com 6012852Sgabeblack@google.comvoid 6112997Sgabeblack@google.comsc_report_handler::report(sc_severity severity, const char *msg_type, 6212997Sgabeblack@google.com const char *msg, int verbosity, const char *file, 6312997Sgabeblack@google.com int line) 6412852Sgabeblack@google.com{ 6513312Sgabeblack@google.com if (severity == SC_INFO && verbosity > sc_gem5::reportVerbosityLevel) 6612997Sgabeblack@google.com return; 6712997Sgabeblack@google.com 6813312Sgabeblack@google.com sc_gem5::ReportSevInfo &sevInfo = sc_gem5::reportSevInfos[severity]; 6913312Sgabeblack@google.com sc_gem5::ReportMsgInfo &msgInfo = sc_gem5::reportMsgInfoMap[msg_type]; 7012997Sgabeblack@google.com 7112997Sgabeblack@google.com sevInfo.count++; 7212997Sgabeblack@google.com msgInfo.count++; 7313312Sgabeblack@google.com msgInfo.sevCounts[severity]++; 7412997Sgabeblack@google.com 7512997Sgabeblack@google.com sc_actions actions = SC_UNSPECIFIED; 7613312Sgabeblack@google.com if (msgInfo.sevActions[severity] != SC_UNSPECIFIED) 7713312Sgabeblack@google.com actions = msgInfo.sevActions[severity]; 7812997Sgabeblack@google.com else if (msgInfo.actions != SC_UNSPECIFIED) 7912997Sgabeblack@google.com actions = msgInfo.actions; 8012997Sgabeblack@google.com else if (sevInfo.actions != SC_UNSPECIFIED) 8112997Sgabeblack@google.com actions = sevInfo.actions; 8212997Sgabeblack@google.com 8313312Sgabeblack@google.com actions &= ~sc_gem5::reportSuppressedActions; 8413312Sgabeblack@google.com actions |= sc_gem5::reportForcedActions; 8512997Sgabeblack@google.com 8613312Sgabeblack@google.com msgInfo.checkLimits(severity, actions); 8713312Sgabeblack@google.com sevInfo.checkLimit(actions); 8812997Sgabeblack@google.com 8912997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 9012997Sgabeblack@google.com sc_report report(severity, msg_type, msg, verbosity, file, line, 9112997Sgabeblack@google.com sc_time::from_value(::sc_gem5::scheduler.getCurTick()), 9212997Sgabeblack@google.com current ? current->name() : nullptr, -1); 9312997Sgabeblack@google.com 9412997Sgabeblack@google.com if (actions & SC_CACHE_REPORT) { 9512997Sgabeblack@google.com if (current) { 9612997Sgabeblack@google.com current->lastReport(&report); 9712997Sgabeblack@google.com } else { 9813312Sgabeblack@google.com sc_gem5::globalReportCache = 9912997Sgabeblack@google.com std::unique_ptr<sc_report>(new sc_report(report)); 10012997Sgabeblack@google.com } 10112997Sgabeblack@google.com } 10212997Sgabeblack@google.com 10313312Sgabeblack@google.com sc_gem5::reportHandlerProc(report, actions); 10412852Sgabeblack@google.com} 10512852Sgabeblack@google.com 10612902Sgabeblack@google.comvoid 10712902Sgabeblack@google.comsc_report_handler::report(sc_severity, int id, const char *msg, 10812902Sgabeblack@google.com const char *file, int line) 10912902Sgabeblack@google.com{ 11012997Sgabeblack@google.com warn("%s:%d %s\n", file, line, msg); 11112902Sgabeblack@google.com warn("%s not implemented.\n", __PRETTY_FUNCTION__); 11212902Sgabeblack@google.com} 11312902Sgabeblack@google.com 11412852Sgabeblack@google.comsc_actions 11512997Sgabeblack@google.comsc_report_handler::set_actions(sc_severity severity, sc_actions actions) 11612852Sgabeblack@google.com{ 11713312Sgabeblack@google.com sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity]; 11812997Sgabeblack@google.com sc_actions previous = info.actions; 11912997Sgabeblack@google.com info.actions = actions; 12012997Sgabeblack@google.com return previous; 12112852Sgabeblack@google.com} 12212852Sgabeblack@google.com 12312852Sgabeblack@google.comsc_actions 12412997Sgabeblack@google.comsc_report_handler::set_actions(const char *msg_type, sc_actions actions) 12512852Sgabeblack@google.com{ 12613312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 12712997Sgabeblack@google.com sc_actions previous = info.actions; 12812997Sgabeblack@google.com info.actions = actions; 12912997Sgabeblack@google.com return previous; 13012852Sgabeblack@google.com} 13112852Sgabeblack@google.com 13212852Sgabeblack@google.comsc_actions 13312997Sgabeblack@google.comsc_report_handler::set_actions( 13412997Sgabeblack@google.com const char *msg_type, sc_severity severity, sc_actions actions) 13512852Sgabeblack@google.com{ 13613312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 13713312Sgabeblack@google.com sc_actions previous = info.sevActions[severity]; 13813312Sgabeblack@google.com info.sevActions[severity] = actions; 13912997Sgabeblack@google.com return previous; 14012852Sgabeblack@google.com} 14112852Sgabeblack@google.com 14212852Sgabeblack@google.comint 14312997Sgabeblack@google.comsc_report_handler::stop_after(sc_severity severity, int limit) 14412852Sgabeblack@google.com{ 14513312Sgabeblack@google.com sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity]; 14612997Sgabeblack@google.com int previous = info.limit; 14712997Sgabeblack@google.com info.limit = limit; 14812997Sgabeblack@google.com return previous; 14912852Sgabeblack@google.com} 15012852Sgabeblack@google.com 15112852Sgabeblack@google.comint 15212852Sgabeblack@google.comsc_report_handler::stop_after(const char *msg_type, int limit) 15312852Sgabeblack@google.com{ 15413312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 15512997Sgabeblack@google.com int previous = info.limit; 15612997Sgabeblack@google.com info.limit = limit; 15712997Sgabeblack@google.com return previous; 15812852Sgabeblack@google.com} 15912852Sgabeblack@google.com 16012852Sgabeblack@google.comint 16112997Sgabeblack@google.comsc_report_handler::stop_after( 16212997Sgabeblack@google.com const char *msg_type, sc_severity severity, int limit) 16312852Sgabeblack@google.com{ 16413312Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type]; 16513312Sgabeblack@google.com int previous = info.sevLimits[severity]; 16613312Sgabeblack@google.com info.sevLimits[severity] = limit; 16712997Sgabeblack@google.com return previous; 16812852Sgabeblack@google.com} 16912852Sgabeblack@google.com 17012852Sgabeblack@google.comint 17112997Sgabeblack@google.comsc_report_handler::get_count(sc_severity severity) 17212852Sgabeblack@google.com{ 17313312Sgabeblack@google.com return sc_gem5::reportSevInfos[severity].count; 17412852Sgabeblack@google.com} 17512852Sgabeblack@google.com 17612852Sgabeblack@google.comint 17712852Sgabeblack@google.comsc_report_handler::get_count(const char *msg_type) 17812852Sgabeblack@google.com{ 17913312Sgabeblack@google.com return sc_gem5::reportMsgInfoMap[msg_type].count; 18012852Sgabeblack@google.com} 18112852Sgabeblack@google.com 18212852Sgabeblack@google.comint 18312997Sgabeblack@google.comsc_report_handler::get_count(const char *msg_type, sc_severity severity) 18412852Sgabeblack@google.com{ 18513312Sgabeblack@google.com return sc_gem5::reportMsgInfoMap[msg_type].sevCounts[severity]; 18612852Sgabeblack@google.com} 18712852Sgabeblack@google.com 18812852Sgabeblack@google.comint 18912997Sgabeblack@google.comsc_report_handler::set_verbosity_level(int vl) 19012852Sgabeblack@google.com{ 19113312Sgabeblack@google.com int previous = sc_gem5::reportVerbosityLevel; 19213312Sgabeblack@google.com sc_gem5::reportVerbosityLevel = vl; 19312997Sgabeblack@google.com return previous; 19412852Sgabeblack@google.com} 19512852Sgabeblack@google.com 19612852Sgabeblack@google.comint 19712852Sgabeblack@google.comsc_report_handler::get_verbosity_level() 19812852Sgabeblack@google.com{ 19913312Sgabeblack@google.com return sc_gem5::reportVerbosityLevel; 20012852Sgabeblack@google.com} 20112852Sgabeblack@google.com 20212852Sgabeblack@google.com 20312852Sgabeblack@google.comsc_actions 20412997Sgabeblack@google.comsc_report_handler::suppress(sc_actions actions) 20512852Sgabeblack@google.com{ 20613312Sgabeblack@google.com sc_actions previous = sc_gem5::reportSuppressedActions; 20713312Sgabeblack@google.com sc_gem5::reportSuppressedActions = actions; 20812997Sgabeblack@google.com return previous; 20912852Sgabeblack@google.com} 21012852Sgabeblack@google.com 21112852Sgabeblack@google.comsc_actions 21212852Sgabeblack@google.comsc_report_handler::suppress() 21312852Sgabeblack@google.com{ 21412997Sgabeblack@google.com return suppress(SC_UNSPECIFIED); 21512852Sgabeblack@google.com} 21612852Sgabeblack@google.com 21712852Sgabeblack@google.comsc_actions 21812997Sgabeblack@google.comsc_report_handler::force(sc_actions actions) 21912852Sgabeblack@google.com{ 22013312Sgabeblack@google.com sc_actions previous = sc_gem5::reportForcedActions; 22113312Sgabeblack@google.com sc_gem5::reportForcedActions = actions; 22212997Sgabeblack@google.com return previous; 22312852Sgabeblack@google.com} 22412852Sgabeblack@google.com 22512852Sgabeblack@google.comsc_actions 22612852Sgabeblack@google.comsc_report_handler::force() 22712852Sgabeblack@google.com{ 22812997Sgabeblack@google.com return force(SC_UNSPECIFIED); 22912852Sgabeblack@google.com} 23012852Sgabeblack@google.com 23112852Sgabeblack@google.com 23212911Sgabeblack@google.comsc_actions 23312997Sgabeblack@google.comsc_report_handler::set_catch_actions(sc_actions actions) 23412911Sgabeblack@google.com{ 23513312Sgabeblack@google.com sc_actions previous = sc_gem5::reportCatchActions; 23613312Sgabeblack@google.com sc_gem5::reportCatchActions = actions; 23712997Sgabeblack@google.com return previous; 23812911Sgabeblack@google.com} 23912911Sgabeblack@google.com 24012911Sgabeblack@google.comsc_actions 24112911Sgabeblack@google.comsc_report_handler::get_catch_actions() 24212911Sgabeblack@google.com{ 24313312Sgabeblack@google.com return sc_gem5::reportCatchActions; 24412911Sgabeblack@google.com} 24512911Sgabeblack@google.com 24612911Sgabeblack@google.com 24712852Sgabeblack@google.comvoid 24812997Sgabeblack@google.comsc_report_handler::set_handler(sc_report_handler_proc proc) 24912852Sgabeblack@google.com{ 25013312Sgabeblack@google.com sc_gem5::reportHandlerProc = proc; 25112852Sgabeblack@google.com} 25212852Sgabeblack@google.com 25312852Sgabeblack@google.comvoid 25412997Sgabeblack@google.comsc_report_handler::default_handler( 25512997Sgabeblack@google.com const sc_report &report, const sc_actions &actions) 25612852Sgabeblack@google.com{ 25712997Sgabeblack@google.com if (actions & SC_DISPLAY) 25812997Sgabeblack@google.com cprintf("\n%s\n", sc_report_compose_message(report)); 25912997Sgabeblack@google.com 26012997Sgabeblack@google.com if ((actions & SC_LOG) && logFile) { 26112997Sgabeblack@google.com ccprintf(*logFile, "%s: %s\n", report.get_time().to_string(), 26212997Sgabeblack@google.com sc_report_compose_message(report)); 26312997Sgabeblack@google.com } 26412997Sgabeblack@google.com if (actions & SC_STOP) { 26512997Sgabeblack@google.com sc_stop_here(report.get_msg_type(), report.get_severity()); 26612997Sgabeblack@google.com sc_stop(); 26712997Sgabeblack@google.com } 26812997Sgabeblack@google.com if (actions & SC_INTERRUPT) 26912997Sgabeblack@google.com sc_interrupt_here(report.get_msg_type(), report.get_severity()); 27012997Sgabeblack@google.com if (actions & SC_ABORT) 27112997Sgabeblack@google.com sc_abort(); 27212997Sgabeblack@google.com if (actions & SC_THROW) { 27312997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 27412997Sgabeblack@google.com if (current) 27512997Sgabeblack@google.com current->isUnwinding(false); 27612997Sgabeblack@google.com throw report; 27712997Sgabeblack@google.com } 27812852Sgabeblack@google.com} 27912852Sgabeblack@google.com 28012852Sgabeblack@google.comsc_actions 28112852Sgabeblack@google.comsc_report_handler::get_new_action_id() 28212852Sgabeblack@google.com{ 28313312Sgabeblack@google.com static sc_actions maxAction = SC_ABORT; 28412997Sgabeblack@google.com maxAction = maxAction << 1; 28512997Sgabeblack@google.com return maxAction; 28612852Sgabeblack@google.com} 28712852Sgabeblack@google.com 28812852Sgabeblack@google.comsc_report * 28912852Sgabeblack@google.comsc_report_handler::get_cached_report() 29012852Sgabeblack@google.com{ 29112997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 29212997Sgabeblack@google.com if (current) 29312997Sgabeblack@google.com return current->lastReport(); 29413312Sgabeblack@google.com return ::sc_gem5::globalReportCache.get(); 29512852Sgabeblack@google.com} 29612852Sgabeblack@google.com 29712852Sgabeblack@google.comvoid 29812852Sgabeblack@google.comsc_report_handler::clear_cached_report() 29912852Sgabeblack@google.com{ 30012997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 30112997Sgabeblack@google.com if (current) { 30212997Sgabeblack@google.com current->lastReport(nullptr); 30312997Sgabeblack@google.com } else { 30413312Sgabeblack@google.com ::sc_gem5::globalReportCache = nullptr; 30512997Sgabeblack@google.com } 30612852Sgabeblack@google.com} 30712852Sgabeblack@google.com 30812852Sgabeblack@google.combool 30912997Sgabeblack@google.comsc_report_handler::set_log_file_name(const char *new_name) 31012852Sgabeblack@google.com{ 31112997Sgabeblack@google.com if (!new_name) { 31212997Sgabeblack@google.com logFile = nullptr; 31312997Sgabeblack@google.com logFileName = nullptr; 31412997Sgabeblack@google.com return false; 31512997Sgabeblack@google.com } else { 31612997Sgabeblack@google.com if (logFileName) 31712997Sgabeblack@google.com return false; 31812997Sgabeblack@google.com logFileName = std::unique_ptr<std::string>(new std::string(new_name)); 31912997Sgabeblack@google.com logFile = std::unique_ptr<std::ofstream>(new std::ofstream(new_name)); 32012997Sgabeblack@google.com return true; 32112997Sgabeblack@google.com } 32212852Sgabeblack@google.com} 32312852Sgabeblack@google.com 32412852Sgabeblack@google.comconst char * 32512852Sgabeblack@google.comsc_report_handler::get_log_file_name() 32612852Sgabeblack@google.com{ 32712997Sgabeblack@google.com if (!logFileName) 32812997Sgabeblack@google.com return nullptr; 32912997Sgabeblack@google.com else 33012997Sgabeblack@google.com return logFileName->c_str(); 33112852Sgabeblack@google.com} 33212852Sgabeblack@google.com 33312852Sgabeblack@google.comvoid 33412852Sgabeblack@google.comsc_interrupt_here(const char *msg_type, sc_severity) 33512852Sgabeblack@google.com{ 33612997Sgabeblack@google.com // Purposefully empty, for setting breakpoints supposedly. 33712852Sgabeblack@google.com} 33812852Sgabeblack@google.com 33912852Sgabeblack@google.comvoid 34012852Sgabeblack@google.comsc_stop_here(const char *msg_type, sc_severity) 34112852Sgabeblack@google.com{ 34212997Sgabeblack@google.com // Purposefully empty, for setting breakpoints supposedly. 34312852Sgabeblack@google.com} 34412852Sgabeblack@google.com 34512921Sgabeblack@google.comconst std::string 34612997Sgabeblack@google.comsc_report_compose_message(const sc_report &report) 34712921Sgabeblack@google.com{ 34812997Sgabeblack@google.com std::ostringstream str; 34912997Sgabeblack@google.com 35013312Sgabeblack@google.com const char *sevName = sc_gem5::reportSeverityNames[report.get_severity()]; 35112997Sgabeblack@google.com int id = report.get_id(); 35212997Sgabeblack@google.com 35312997Sgabeblack@google.com str << sevName << ": "; 35412997Sgabeblack@google.com if (id >= 0) { 35512997Sgabeblack@google.com ccprintf(str, "(%c%d) ", sevName[0], id); 35612997Sgabeblack@google.com } 35712997Sgabeblack@google.com str << report.get_msg_type(); 35812997Sgabeblack@google.com 35912997Sgabeblack@google.com const char *msg = report.get_msg(); 36013080Sgabeblack@google.com if (msg && msg[0]) 36112997Sgabeblack@google.com str << ": " << msg; 36212997Sgabeblack@google.com 36312997Sgabeblack@google.com if (report.get_severity() > SC_INFO) { 36412997Sgabeblack@google.com ccprintf(str, "\nIn file: %s:%d", report.get_file_name(), 36512997Sgabeblack@google.com report.get_line_number()); 36612997Sgabeblack@google.com 36712997Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 36812997Sgabeblack@google.com const char *name = report.get_process_name(); 36912997Sgabeblack@google.com if (current && sc_is_running() && name) { 37012997Sgabeblack@google.com ccprintf(str, "\nIn process: %s @ %s", name, 37112997Sgabeblack@google.com report.get_time().to_string()); 37212997Sgabeblack@google.com } 37312997Sgabeblack@google.com } 37412997Sgabeblack@google.com 37512997Sgabeblack@google.com return str.str(); 37612921Sgabeblack@google.com} 37712921Sgabeblack@google.com 37812921Sgabeblack@google.combool 37912921Sgabeblack@google.comsc_report_close_default_log() 38012921Sgabeblack@google.com{ 38112997Sgabeblack@google.com if (logFile) { 38212997Sgabeblack@google.com logFile = nullptr; 38312997Sgabeblack@google.com logFileName = nullptr; 38412997Sgabeblack@google.com return false; 38512997Sgabeblack@google.com } 38612997Sgabeblack@google.com return true; 38712921Sgabeblack@google.com} 38812921Sgabeblack@google.com 38912852Sgabeblack@google.com} // namespace sc_core 390