sc_report_handler.cc revision 13182:9e030f636a8c
11758SN/A/* 21762SN/A * Copyright 2018 Google, Inc. 31758SN/A * 41758SN/A * Redistribution and use in source and binary forms, with or without 51758SN/A * modification, are permitted provided that the following conditions are 61758SN/A * met: redistributions of source code must retain the above copyright 71758SN/A * notice, this list of conditions and the following disclaimer; 81758SN/A * redistributions in binary form must reproduce the above copyright 91758SN/A * notice, this list of conditions and the following disclaimer in the 101758SN/A * documentation and/or other materials provided with the distribution; 111758SN/A * neither the name of the copyright holders nor the names of its 121758SN/A * contributors may be used to endorse or promote products derived from 131758SN/A * this software without specific prior written permission. 141758SN/A * 151758SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161758SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171758SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 181758SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 191758SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 201758SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 211758SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 221758SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231758SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 241758SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 251758SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 261758SN/A * 272665Ssaidi@eecs.umich.edu * Authors: Gabe Black 282665Ssaidi@eecs.umich.edu */ 292665Ssaidi@eecs.umich.edu 301758SN/A#include <fstream> 312SN/A#include <map> 322984Sgblack@eecs.umich.edu#include <sstream> 33732SN/A#include <string> 343565Sgblack@eecs.umich.edu 35732SN/A#include "base/logging.hh" 362984Sgblack@eecs.umich.edu#include "systemc/core/process.hh" 373536Sgblack@eecs.umich.edu#include "systemc/core/scheduler.hh" 38732SN/A#include "systemc/ext/core/sc_main.hh" 39732SN/A#include "systemc/ext/utils/sc_report_handler.hh" 401858SN/A 411717SN/Anamespace sc_core 422683Sktlim@umich.edu{ 432680Sktlim@umich.edu 44676SN/Anamespace 452710Sstever@eecs.umich.edu{ 462SN/A 471858SN/Astd::unique_ptr<std::string> logFileName; 482SN/Astd::unique_ptr<std::ofstream> logFile; 491147SN/A 501147SN/Astruct ReportCatInfo 512SN/A{ 522SN/A explicit ReportCatInfo(sc_actions actions) : 532SN/A actions(actions), count(0), limit(-1) 542SN/A {} 552SN/A ReportCatInfo() : ReportCatInfo(SC_UNSPECIFIED) {} 562680Sktlim@umich.edu 572SN/A bool 582680Sktlim@umich.edu checkLimit(sc_actions &actions) 59190SN/A { 602680Sktlim@umich.edu if (limit == 0 || count < limit) 612680Sktlim@umich.edu return false; 622114SN/A if (limit != -1) 633468Sgblack@eecs.umich.edu actions |= SC_STOP; 642700Sktlim@umich.edu return true; 654172Ssaidi@eecs.umich.edu } 662680Sktlim@umich.edu 672700Sktlim@umich.edu sc_actions actions; 682700Sktlim@umich.edu int count; 692SN/A int limit; 702SN/A}; 712SN/A 721133SN/Aconst char *severityNames[] = { 73716SN/A [SC_INFO] = "Info", 741133SN/A [SC_WARNING] = "Warning", 75716SN/A [SC_ERROR] = "Error", 76716SN/A [SC_FATAL] = "Fatal" 77716SN/A}; 78716SN/A 79716SN/AReportCatInfo catForSeverity[SC_MAX_SEVERITY] = 80716SN/A{ 814172Ssaidi@eecs.umich.edu [SC_INFO] = ReportCatInfo(SC_DEFAULT_INFO_ACTIONS), 82716SN/A [SC_WARNING] = ReportCatInfo(SC_DEFAULT_WARNING_ACTIONS), 83716SN/A [SC_ERROR] = ReportCatInfo(SC_DEFAULT_ERROR_ACTIONS), 844172Ssaidi@eecs.umich.edu [SC_FATAL] = ReportCatInfo(SC_DEFAULT_FATAL_ACTIONS) 85716SN/A}; 86716SN/A 874172Ssaidi@eecs.umich.edustd::map<std::string, ReportCatInfo> catForMsgType; 88716SN/Astd::map<std::pair<std::string, sc_severity>, ReportCatInfo> 89716SN/A catForSeverityAndMsgType; 90716SN/A 91716SN/Aint verbosityLevel = SC_MEDIUM; 92716SN/A 93716SN/Asc_actions suppressedActions = SC_UNSPECIFIED; 94716SN/Asc_actions forcedActions = SC_UNSPECIFIED; 951133SN/Asc_actions catchActions = SC_UNSPECIFIED; 96716SN/A 97716SN/Asc_report_handler_proc reportHandlerProc = &sc_report_handler::default_handler; 98716SN/A 99716SN/Asc_actions maxAction = SC_ABORT; 100716SN/A 101716SN/Astd::unique_ptr<sc_report> globalReportCache; 102716SN/A 103716SN/A} // anonymous namespace 104716SN/A 105716SN/Avoid 106716SN/Asc_report_handler::report(sc_severity severity, const char *msg_type, 107716SN/A const char *msg, const char *file, int line) 1084172Ssaidi@eecs.umich.edu{ 1094172Ssaidi@eecs.umich.edu report(severity, msg_type, msg, SC_MEDIUM, file, line); 1104172Ssaidi@eecs.umich.edu} 1112147SN/A 112716SN/Avoid 1134172Ssaidi@eecs.umich.edusc_report_handler::report(sc_severity severity, const char *msg_type, 114716SN/A const char *msg, int verbosity, const char *file, 115716SN/A int line) 116716SN/A{ 117716SN/A if (severity == SC_INFO && verbosity > verbosityLevel) 1181133SN/A return; 119716SN/A 1201133SN/A ReportCatInfo &sevInfo = catForSeverity[severity]; 121716SN/A ReportCatInfo &msgInfo = catForMsgType[msg_type]; 122716SN/A ReportCatInfo &sevMsgInfo = catForSeverityAndMsgType[ 123739SN/A std::make_pair(std::string(msg_type), severity)]; 124739SN/A 1252683Sktlim@umich.edu sevInfo.count++; 1262683Sktlim@umich.edu msgInfo.count++; 127716SN/A sevMsgInfo.count++; 128716SN/A 1292SN/A sc_actions actions = SC_UNSPECIFIED; 1302683Sktlim@umich.edu if (sevMsgInfo.actions != SC_UNSPECIFIED) 1312SN/A actions = sevMsgInfo.actions; 1323521Sgblack@eecs.umich.edu else if (msgInfo.actions != SC_UNSPECIFIED) 1332147SN/A actions = msgInfo.actions; 1342SN/A else if (sevInfo.actions != SC_UNSPECIFIED) 1354172Ssaidi@eecs.umich.edu actions = sevInfo.actions; 1362SN/A 1372SN/A actions &= ~suppressedActions; 1382341SN/A actions |= forcedActions; 1392341SN/A 1402SN/A if (sevMsgInfo.checkLimit(actions) && msgInfo.checkLimit(actions)) 1412SN/A sevInfo.checkLimit(actions); 1422SN/A 1432154SN/A ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 1442SN/A sc_report report(severity, msg_type, msg, verbosity, file, line, 1452SN/A sc_time::from_value(::sc_gem5::scheduler.getCurTick()), 1462245SN/A current ? current->name() : nullptr, -1); 1472245SN/A 1482245SN/A if (actions & SC_CACHE_REPORT) { 1493459Sgblack@eecs.umich.edu if (current) { 1502245SN/A current->lastReport(&report); 1512245SN/A } else { 1522245SN/A globalReportCache = 1532245SN/A std::unique_ptr<sc_report>(new sc_report(report)); 1542245SN/A } 1553459Sgblack@eecs.umich.edu } 1562245SN/A 1572245SN/A reportHandlerProc(report, actions); 1584997Sgblack@eecs.umich.edu} 1594997Sgblack@eecs.umich.edu 1604997Sgblack@eecs.umich.eduvoid 1614997Sgblack@eecs.umich.edusc_report_handler::report(sc_severity, int id, const char *msg, 1624997Sgblack@eecs.umich.edu const char *file, int line) 1634997Sgblack@eecs.umich.edu{ 1644997Sgblack@eecs.umich.edu warn("%s:%d %s\n", file, line, msg); 1654997Sgblack@eecs.umich.edu warn("%s not implemented.\n", __PRETTY_FUNCTION__); 1664997Sgblack@eecs.umich.edu} 1674997Sgblack@eecs.umich.edu 1684997Sgblack@eecs.umich.edusc_actions 1694997Sgblack@eecs.umich.edusc_report_handler::set_actions(sc_severity severity, sc_actions actions) 1704997Sgblack@eecs.umich.edu{ 1714997Sgblack@eecs.umich.edu ReportCatInfo &info = catForSeverity[severity]; 1724997Sgblack@eecs.umich.edu sc_actions previous = info.actions; 1734997Sgblack@eecs.umich.edu info.actions = actions; 1744997Sgblack@eecs.umich.edu return previous; 1754997Sgblack@eecs.umich.edu} 1762159SN/A 1773468Sgblack@eecs.umich.edusc_actions 1782159SN/Asc_report_handler::set_actions(const char *msg_type, sc_actions actions) 1795543Ssaidi@eecs.umich.edu{ 1802SN/A ReportCatInfo &info = catForMsgType[msg_type]; 1812SN/A sc_actions previous = info.actions; 1823459Sgblack@eecs.umich.edu info.actions = actions; 1833459Sgblack@eecs.umich.edu return previous; 1843459Sgblack@eecs.umich.edu} 1853459Sgblack@eecs.umich.edu 1863459Sgblack@eecs.umich.edusc_actions 1873459Sgblack@eecs.umich.edusc_report_handler::set_actions( 1883459Sgblack@eecs.umich.edu const char *msg_type, sc_severity severity, sc_actions actions) 1893459Sgblack@eecs.umich.edu{ 1903459Sgblack@eecs.umich.edu ReportCatInfo &info = catForSeverityAndMsgType[ 1913459Sgblack@eecs.umich.edu std::make_pair(std::string(msg_type), severity)]; 1923459Sgblack@eecs.umich.edu sc_actions previous = info.actions; 1933459Sgblack@eecs.umich.edu info.actions = actions; 1943459Sgblack@eecs.umich.edu return previous; 1953459Sgblack@eecs.umich.edu} 1963459Sgblack@eecs.umich.edu 1973459Sgblack@eecs.umich.eduint 1983459Sgblack@eecs.umich.edusc_report_handler::stop_after(sc_severity severity, int limit) 1993459Sgblack@eecs.umich.edu{ 2003459Sgblack@eecs.umich.edu ReportCatInfo &info = catForSeverity[severity]; 2013459Sgblack@eecs.umich.edu int previous = info.limit; 2023459Sgblack@eecs.umich.edu info.limit = limit; 2033459Sgblack@eecs.umich.edu return previous; 2043459Sgblack@eecs.umich.edu} 2053459Sgblack@eecs.umich.edu 2063459Sgblack@eecs.umich.eduint 2072SN/Asc_report_handler::stop_after(const char *msg_type, int limit) 2083459Sgblack@eecs.umich.edu{ 2093459Sgblack@eecs.umich.edu ReportCatInfo &info = catForMsgType[msg_type]; 2103459Sgblack@eecs.umich.edu int previous = info.limit; 2113459Sgblack@eecs.umich.edu info.limit = limit; 2123459Sgblack@eecs.umich.edu return previous; 2133459Sgblack@eecs.umich.edu} 2143459Sgblack@eecs.umich.edu 2153459Sgblack@eecs.umich.eduint 2163459Sgblack@eecs.umich.edusc_report_handler::stop_after( 2173459Sgblack@eecs.umich.edu const char *msg_type, sc_severity severity, int limit) 2183459Sgblack@eecs.umich.edu{ 2193459Sgblack@eecs.umich.edu ReportCatInfo &info = catForSeverityAndMsgType[ 2203459Sgblack@eecs.umich.edu std::make_pair(std::string(msg_type), severity)]; 2213459Sgblack@eecs.umich.edu int previous = info.limit; 2223459Sgblack@eecs.umich.edu info.limit = limit; 2233459Sgblack@eecs.umich.edu return previous; 2243459Sgblack@eecs.umich.edu} 2252SN/A 2262SN/Aint 2272SN/Asc_report_handler::get_count(sc_severity severity) 2282SN/A{ 2293459Sgblack@eecs.umich.edu return catForSeverity[severity].count; 230597SN/A} 2312680Sktlim@umich.edu 232597SN/Aint 233597SN/Asc_report_handler::get_count(const char *msg_type) 2343459Sgblack@eecs.umich.edu{ 2352SN/A return catForMsgType[msg_type].count; 2362SN/A} 2372SN/A 2383459Sgblack@eecs.umich.eduint 2393459Sgblack@eecs.umich.edusc_report_handler::get_count(const char *msg_type, sc_severity severity) 2403459Sgblack@eecs.umich.edu{ 2413459Sgblack@eecs.umich.edu return catForSeverityAndMsgType[ 2423459Sgblack@eecs.umich.edu std::make_pair(std::string(msg_type), severity)].count; 2432SN/A} 2442SN/A 2452SN/Aint 2463459Sgblack@eecs.umich.edusc_report_handler::set_verbosity_level(int vl) 2472SN/A{ 2485004Sgblack@eecs.umich.edu int previous = verbosityLevel; 2495004Sgblack@eecs.umich.edu verbosityLevel = vl; 2502SN/A return previous; 2515004Sgblack@eecs.umich.edu} 2525004Sgblack@eecs.umich.edu 2535004Sgblack@eecs.umich.eduint 2545004Sgblack@eecs.umich.edusc_report_handler::get_verbosity_level() 2555004Sgblack@eecs.umich.edu{ 2565004Sgblack@eecs.umich.edu return verbosityLevel; 2575004Sgblack@eecs.umich.edu} 2582SN/A 2592SN/A 2602SN/Asc_actions 2612SN/Asc_report_handler::suppress(sc_actions actions) 2623459Sgblack@eecs.umich.edu{ 2633459Sgblack@eecs.umich.edu sc_actions previous = suppressedActions; 2643459Sgblack@eecs.umich.edu suppressedActions = actions; 2653459Sgblack@eecs.umich.edu return previous; 2663459Sgblack@eecs.umich.edu} 2673459Sgblack@eecs.umich.edu 2683459Sgblack@eecs.umich.edusc_actions 2693459Sgblack@eecs.umich.edusc_report_handler::suppress() 2703459Sgblack@eecs.umich.edu{ 2713468Sgblack@eecs.umich.edu return suppress(SC_UNSPECIFIED); 2722SN/A} 2732SN/A 2742SN/Asc_actions 2752SN/Asc_report_handler::force(sc_actions actions) 2763468Sgblack@eecs.umich.edu{ 2772SN/A sc_actions previous = forcedActions; 2782SN/A forcedActions = actions; 2792SN/A return previous; 2802SN/A} 2812SN/A 2822SN/Asc_actions 2832SN/Asc_report_handler::force() 2842SN/A{ 2852SN/A return force(SC_UNSPECIFIED); 2862SN/A} 2872SN/A 2883468Sgblack@eecs.umich.edu 2892680Sktlim@umich.edusc_actions 2902SN/Asc_report_handler::set_catch_actions(sc_actions actions) 291710SN/A{ 2922SN/A sc_actions previous = catchActions; 2932680Sktlim@umich.edu catchActions = actions; 2943468Sgblack@eecs.umich.edu return previous; 2952SN/A} 2962SN/A 2973459Sgblack@eecs.umich.edusc_actions 2983459Sgblack@eecs.umich.edusc_report_handler::get_catch_actions() 2993459Sgblack@eecs.umich.edu{ 3003459Sgblack@eecs.umich.edu return catchActions; 3013459Sgblack@eecs.umich.edu} 3023459Sgblack@eecs.umich.edu 3033459Sgblack@eecs.umich.edu 3043459Sgblack@eecs.umich.eduvoid 3053459Sgblack@eecs.umich.edusc_report_handler::set_handler(sc_report_handler_proc proc) 3063459Sgblack@eecs.umich.edu{ 3073459Sgblack@eecs.umich.edu reportHandlerProc = proc; 3083459Sgblack@eecs.umich.edu} 3093459Sgblack@eecs.umich.edu 3103459Sgblack@eecs.umich.eduvoid 3113459Sgblack@eecs.umich.edusc_report_handler::default_handler( 3123459Sgblack@eecs.umich.edu const sc_report &report, const sc_actions &actions) 3133459Sgblack@eecs.umich.edu{ 3143459Sgblack@eecs.umich.edu if (actions & SC_DISPLAY) 3153459Sgblack@eecs.umich.edu cprintf("\n%s\n", sc_report_compose_message(report)); 3163459Sgblack@eecs.umich.edu 3173459Sgblack@eecs.umich.edu if ((actions & SC_LOG) && logFile) { 3183459Sgblack@eecs.umich.edu ccprintf(*logFile, "%s: %s\n", report.get_time().to_string(), 3193459Sgblack@eecs.umich.edu sc_report_compose_message(report)); 3203459Sgblack@eecs.umich.edu } 3213459Sgblack@eecs.umich.edu if (actions & SC_STOP) { 3223459Sgblack@eecs.umich.edu sc_stop_here(report.get_msg_type(), report.get_severity()); 3233459Sgblack@eecs.umich.edu sc_stop(); 3242SN/A } 3252SN/A if (actions & SC_INTERRUPT) 3262SN/A sc_interrupt_here(report.get_msg_type(), report.get_severity()); 3272SN/A if (actions & SC_ABORT) 3283459Sgblack@eecs.umich.edu sc_abort(); 329596SN/A if (actions & SC_THROW) { 330596SN/A ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 331596SN/A if (current) 332596SN/A current->isUnwinding(false); 333596SN/A throw report; 334596SN/A } 3353459Sgblack@eecs.umich.edu} 336596SN/A 337596SN/Asc_actions 338596SN/Asc_report_handler::get_new_action_id() 339596SN/A{ 340596SN/A maxAction = maxAction << 1; 341596SN/A return maxAction; 3423459Sgblack@eecs.umich.edu} 3432SN/A 344710SN/Asc_report_handler_proc 3452SN/Asc_report_handler::get_handler() 3464997Sgblack@eecs.umich.edu{ 3472680Sktlim@umich.edu return reportHandlerProc; 3482680Sktlim@umich.edu} 3494997Sgblack@eecs.umich.edu 3502SN/Asc_report * 3512SN/Asc_report_handler::get_cached_report() 3523459Sgblack@eecs.umich.edu{ 3532SN/A ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 3542SN/A if (current) 3552SN/A return current->lastReport(); 3562SN/A return globalReportCache.get(); 3573459Sgblack@eecs.umich.edu} 3582SN/A 3592SN/Avoid 3602SN/Asc_report_handler::clear_cached_report() 3612SN/A{ 3623459Sgblack@eecs.umich.edu ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 3633459Sgblack@eecs.umich.edu if (current) { 3642SN/A current->lastReport(nullptr); 3652SN/A } else { 3662SN/A globalReportCache = nullptr; 3672SN/A } 3683459Sgblack@eecs.umich.edu} 3692SN/A 3702SN/Abool 3712SN/Asc_report_handler::set_log_file_name(const char *new_name) 3722SN/A{ 3732SN/A if (!new_name) { 3742SN/A logFile = nullptr; 3752SN/A logFileName = nullptr; 3764997Sgblack@eecs.umich.edu return false; 3772680Sktlim@umich.edu } else { 3782680Sktlim@umich.edu if (logFileName) 3794997Sgblack@eecs.umich.edu return false; 3802SN/A logFileName = std::unique_ptr<std::string>(new std::string(new_name)); 3812SN/A logFile = std::unique_ptr<std::ofstream>(new std::ofstream(new_name)); 3823459Sgblack@eecs.umich.edu return true; 3834997Sgblack@eecs.umich.edu } 3842330SN/A} 3852680Sktlim@umich.edu 3863548Sgblack@eecs.umich.educonst char * 3872341SN/Asc_report_handler::get_log_file_name() 3882680Sktlim@umich.edu{ 3893548Sgblack@eecs.umich.edu if (!logFileName) 3902330SN/A return nullptr; 3914997Sgblack@eecs.umich.edu else 3922SN/A return logFileName->c_str(); 3933459Sgblack@eecs.umich.edu} 3942SN/A 3952SN/Avoid 3962SN/Asc_interrupt_here(const char *msg_type, sc_severity) 3972SN/A{ 3983459Sgblack@eecs.umich.edu // Purposefully empty, for setting breakpoints supposedly. 3992SN/A} 4002SN/A 4012SN/Avoid 4022SN/Asc_stop_here(const char *msg_type, sc_severity) 4033459Sgblack@eecs.umich.edu{ 4042SN/A // Purposefully empty, for setting breakpoints supposedly. 4052SN/A} 4062SN/A 4072SN/Aconst std::string 4083459Sgblack@eecs.umich.edusc_report_compose_message(const sc_report &report) 4092SN/A{ 4102SN/A std::ostringstream str; 4112SN/A 4122SN/A const char *sevName = severityNames[report.get_severity()]; 4133459Sgblack@eecs.umich.edu int id = report.get_id(); 4142SN/A 4152SN/A str << sevName << ": "; 4162SN/A if (id >= 0) { 4173459Sgblack@eecs.umich.edu ccprintf(str, "(%c%d) ", sevName[0], id); 4183459Sgblack@eecs.umich.edu } 4192SN/A str << report.get_msg_type(); 4202SN/A 4212SN/A const char *msg = report.get_msg(); 4223459Sgblack@eecs.umich.edu if (msg && msg[0]) 4232SN/A str << ": " << msg; 4242SN/A 4252SN/A if (report.get_severity() > SC_INFO) { 4263459Sgblack@eecs.umich.edu ccprintf(str, "\nIn file: %s:%d", report.get_file_name(), 4273459Sgblack@eecs.umich.edu report.get_line_number()); 4282SN/A 4292SN/A ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 4302SN/A const char *name = report.get_process_name(); 4313459Sgblack@eecs.umich.edu if (current && sc_is_running() && name) { 4322SN/A ccprintf(str, "\nIn process: %s @ %s", name, 4332SN/A report.get_time().to_string()); 4342SN/A } 4353459Sgblack@eecs.umich.edu } 4362SN/A 4372SN/A return str.str(); 4382SN/A} 4393459Sgblack@eecs.umich.edu 4403459Sgblack@eecs.umich.edubool 4412SN/Asc_report_close_default_log() 4422SN/A{ 4432SN/A if (logFile) { 4442SN/A logFile = nullptr; 4453459Sgblack@eecs.umich.edu logFileName = nullptr; 4463459Sgblack@eecs.umich.edu return false; 4473459Sgblack@eecs.umich.edu } 4483459Sgblack@eecs.umich.edu return true; 4493459Sgblack@eecs.umich.edu} 4502SN/A 4513468Sgblack@eecs.umich.edu} // namespace sc_core 4522SN/A