sc_report_handler.cc revision 13401
112863Sgabeblack@google.com/* 212863Sgabeblack@google.com * Copyright 2018 Google, Inc. 312863Sgabeblack@google.com * 412863Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512863Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612863Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712863Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812863Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912863Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012863Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112863Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212863Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312863Sgabeblack@google.com * this software without specific prior written permission. 1412863Sgabeblack@google.com * 1512863Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612863Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712863Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812863Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912863Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012863Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112863Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212863Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312863Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412863Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512863Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612863Sgabeblack@google.com * 2712863Sgabeblack@google.com * Authors: Gabe Black 2812863Sgabeblack@google.com */ 2912863Sgabeblack@google.com 3012863Sgabeblack@google.com#include <fstream> 3112863Sgabeblack@google.com#include <map> 3212950Sgabeblack@google.com#include <sstream> 3312863Sgabeblack@google.com#include <string> 3412863Sgabeblack@google.com 3513317Sgabeblack@google.com#include "base/cprintf.hh" 3613191Sgabeblack@google.com#include "systemc/core/process.hh" 3713091Sgabeblack@google.com#include "systemc/core/scheduler.hh" 3813079Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 3912863Sgabeblack@google.com#include "systemc/ext/utils/messages.hh" 4012950Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh" 4112863Sgabeblack@google.com#include "systemc/utils/report.hh" 4212863Sgabeblack@google.com 4312863Sgabeblack@google.comnamespace sc_core 4412863Sgabeblack@google.com{ 4512863Sgabeblack@google.com 4612863Sgabeblack@google.comnamespace 4712950Sgabeblack@google.com{ 4812863Sgabeblack@google.com 4912863Sgabeblack@google.comstd::unique_ptr<std::string> logFileName; 5012863Sgabeblack@google.comstd::unique_ptr<std::ofstream> logFile; 5113303Sgabeblack@google.com 5213303Sgabeblack@google.com} // anonymous namespace 5313191Sgabeblack@google.com 5413191Sgabeblack@google.comvoid 5513291Sgabeblack@google.comsc_report_handler::report(sc_severity severity, const char *msg_type, 5612950Sgabeblack@google.com const char *msg, const char *file, int line) 5712950Sgabeblack@google.com{ 5812950Sgabeblack@google.com report(severity, msg_type, msg, SC_MEDIUM, file, line); 5912950Sgabeblack@google.com} 6012950Sgabeblack@google.com 6113079Sgabeblack@google.comvoid 6213079Sgabeblack@google.comsc_report_handler::report(sc_severity severity, const char *msg_type, 6313268Sgabeblack@google.com const char *msg, int verbosity, const char *file, 6413268Sgabeblack@google.com int line) 6513079Sgabeblack@google.com{ 6613268Sgabeblack@google.com if (!msg_type) 6713268Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 6813268Sgabeblack@google.com 6913268Sgabeblack@google.com if (severity == SC_INFO && verbosity > sc_gem5::reportVerbosityLevel) 7013268Sgabeblack@google.com return; 7113268Sgabeblack@google.com 7213079Sgabeblack@google.com sc_gem5::ReportSevInfo &sevInfo = sc_gem5::reportSevInfos[severity]; 7313079Sgabeblack@google.com sc_gem5::ReportMsgInfo &msgInfo = sc_gem5::reportMsgInfoMap()[msg_type]; 7412982Sgabeblack@google.com 7512863Sgabeblack@google.com sevInfo.count++; 7612950Sgabeblack@google.com msgInfo.count++; 7712863Sgabeblack@google.com msgInfo.sevCounts[severity]++; 7812950Sgabeblack@google.com 7912950Sgabeblack@google.com sc_actions actions = SC_UNSPECIFIED; 8012863Sgabeblack@google.com if (msgInfo.sevActions[severity] != SC_UNSPECIFIED) 8113268Sgabeblack@google.com actions = msgInfo.sevActions[severity]; 8213268Sgabeblack@google.com else if (msgInfo.actions != SC_UNSPECIFIED) 8313268Sgabeblack@google.com actions = msgInfo.actions; 8413268Sgabeblack@google.com else if (sevInfo.actions != SC_UNSPECIFIED) 8513268Sgabeblack@google.com actions = sevInfo.actions; 8613268Sgabeblack@google.com 8713268Sgabeblack@google.com actions &= ~sc_gem5::reportSuppressedActions; 8813268Sgabeblack@google.com actions |= sc_gem5::reportForcedActions; 8913268Sgabeblack@google.com 9013268Sgabeblack@google.com msgInfo.checkLimits(severity, actions); 9113268Sgabeblack@google.com sevInfo.checkLimit(actions); 9212863Sgabeblack@google.com 9312863Sgabeblack@google.com ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 9412863Sgabeblack@google.com sc_report report(severity, msg_type, msg, verbosity, file, line, 9512863Sgabeblack@google.com sc_time::from_value(::sc_gem5::scheduler.getCurTick()), 9612863Sgabeblack@google.com current ? current->name() : nullptr, msgInfo.id); 9713268Sgabeblack@google.com 9813268Sgabeblack@google.com if (actions & SC_CACHE_REPORT) { 9913268Sgabeblack@google.com if (current) { 10012950Sgabeblack@google.com current->lastReport(&report); 10113268Sgabeblack@google.com } else { 10212950Sgabeblack@google.com sc_gem5::globalReportCache = 10313268Sgabeblack@google.com std::unique_ptr<sc_report>(new sc_report(report)); 10412863Sgabeblack@google.com } 10512863Sgabeblack@google.com } 10613091Sgabeblack@google.com 10713091Sgabeblack@google.com sc_gem5::reportHandlerProc(report, actions); 10813091Sgabeblack@google.com} 10913091Sgabeblack@google.com 11013091Sgabeblack@google.comvoid 11113091Sgabeblack@google.comsc_report_handler::report(sc_severity severity, int id, const char *msg, 11213091Sgabeblack@google.com const char *file, int line) 11313091Sgabeblack@google.com{ 11413091Sgabeblack@google.com std::string &msg_type = sc_gem5::reportIdToMsgMap()[id]; 11513291Sgabeblack@google.com 11613091Sgabeblack@google.com if (sc_gem5::reportWarningsAsErrors && severity == SC_WARNING) 11713091Sgabeblack@google.com severity = SC_ERROR; 11813091Sgabeblack@google.com 11913091Sgabeblack@google.com report(severity, msg_type.c_str(), msg, file, line); 12013091Sgabeblack@google.com} 12113091Sgabeblack@google.com 12213091Sgabeblack@google.comsc_actions 12313091Sgabeblack@google.comsc_report_handler::set_actions(sc_severity severity, sc_actions actions) 12413291Sgabeblack@google.com{ 12513091Sgabeblack@google.com sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity]; 12613091Sgabeblack@google.com sc_actions previous = info.actions; 12713191Sgabeblack@google.com info.actions = actions; 12813191Sgabeblack@google.com return previous; 12913191Sgabeblack@google.com} 13013268Sgabeblack@google.com 13113268Sgabeblack@google.comsc_actions 13213268Sgabeblack@google.comsc_report_handler::set_actions(const char *msg_type, sc_actions actions) 13313268Sgabeblack@google.com{ 13413268Sgabeblack@google.com if (!msg_type) 13513268Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 13613268Sgabeblack@google.com 13713268Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap()[msg_type]; 13813268Sgabeblack@google.com sc_actions previous = info.actions; 13913268Sgabeblack@google.com info.actions = actions; 14013191Sgabeblack@google.com return previous; 14113191Sgabeblack@google.com} 14213191Sgabeblack@google.com 14313191Sgabeblack@google.comsc_actions 14413191Sgabeblack@google.comsc_report_handler::set_actions( 14513191Sgabeblack@google.com const char *msg_type, sc_severity severity, sc_actions actions) 14613191Sgabeblack@google.com{ 14713317Sgabeblack@google.com if (!msg_type) 14813191Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 14913268Sgabeblack@google.com 15013268Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap()[msg_type]; 15113268Sgabeblack@google.com sc_actions previous = info.sevActions[severity]; 15213268Sgabeblack@google.com info.sevActions[severity] = actions; 15313268Sgabeblack@google.com return previous; 15413268Sgabeblack@google.com} 15513268Sgabeblack@google.com 15613268Sgabeblack@google.comint 15713268Sgabeblack@google.comsc_report_handler::stop_after(sc_severity severity, int limit) 15813268Sgabeblack@google.com{ 15913191Sgabeblack@google.com sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity]; 16013191Sgabeblack@google.com int previous = info.limit; 16113191Sgabeblack@google.com info.limit = limit; 16213191Sgabeblack@google.com return previous; 16313191Sgabeblack@google.com} 16413268Sgabeblack@google.com 16513268Sgabeblack@google.comint 16613268Sgabeblack@google.comsc_report_handler::stop_after(const char *msg_type, int limit) 16713268Sgabeblack@google.com{ 16813268Sgabeblack@google.com if (!msg_type) 16913268Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 17013268Sgabeblack@google.com 17113268Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap()[msg_type]; 17213268Sgabeblack@google.com int previous = info.limit; 17313268Sgabeblack@google.com info.limit = limit; 17413191Sgabeblack@google.com return previous; 17513191Sgabeblack@google.com} 17613191Sgabeblack@google.com 17713191Sgabeblack@google.comint 17813191Sgabeblack@google.comsc_report_handler::stop_after( 17913268Sgabeblack@google.com const char *msg_type, sc_severity severity, int limit) 18013268Sgabeblack@google.com{ 18113268Sgabeblack@google.com if (!msg_type) 18213268Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 18313268Sgabeblack@google.com 18413268Sgabeblack@google.com sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap()[msg_type]; 18513268Sgabeblack@google.com int previous = info.sevLimits[severity]; 18613268Sgabeblack@google.com info.sevLimits[severity] = limit; 18713268Sgabeblack@google.com return previous; 18813268Sgabeblack@google.com} 18913191Sgabeblack@google.com 19013191Sgabeblack@google.comint 19112863Sgabeblack@google.comsc_report_handler::get_count(sc_severity severity) 19212950Sgabeblack@google.com{ 19312863Sgabeblack@google.com return sc_gem5::reportSevInfos[severity].count; 19412950Sgabeblack@google.com} 19512950Sgabeblack@google.com 19612950Sgabeblack@google.comint 19712863Sgabeblack@google.comsc_report_handler::get_count(const char *msg_type) 19812863Sgabeblack@google.com{ 19912950Sgabeblack@google.com if (!msg_type) 20013079Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 20113079Sgabeblack@google.com 20213317Sgabeblack@google.com return sc_gem5::reportMsgInfoMap()[msg_type].count; 20313317Sgabeblack@google.com} 20413079Sgabeblack@google.com 20513079Sgabeblack@google.comint 20613079Sgabeblack@google.comsc_report_handler::get_count(const char *msg_type, sc_severity severity) 20713079Sgabeblack@google.com{ 20812950Sgabeblack@google.com if (!msg_type) 20912950Sgabeblack@google.com msg_type = SC_ID_UNKNOWN_ERROR_; 21012950Sgabeblack@google.com 21112950Sgabeblack@google.com return sc_gem5::reportMsgInfoMap()[msg_type].sevCounts[severity]; 21212950Sgabeblack@google.com} 21313046Sgabeblack@google.com 21412982Sgabeblack@google.comint 21512950Sgabeblack@google.comsc_report_handler::set_verbosity_level(int vl) 216{ 217 int previous = sc_gem5::reportVerbosityLevel; 218 sc_gem5::reportVerbosityLevel = vl; 219 return previous; 220} 221 222int 223sc_report_handler::get_verbosity_level() 224{ 225 return sc_gem5::reportVerbosityLevel; 226} 227 228 229sc_actions 230sc_report_handler::suppress(sc_actions actions) 231{ 232 sc_actions previous = sc_gem5::reportSuppressedActions; 233 sc_gem5::reportSuppressedActions = actions; 234 return previous; 235} 236 237sc_actions 238sc_report_handler::suppress() 239{ 240 return suppress(SC_UNSPECIFIED); 241} 242 243sc_actions 244sc_report_handler::force(sc_actions actions) 245{ 246 sc_actions previous = sc_gem5::reportForcedActions; 247 sc_gem5::reportForcedActions = actions; 248 return previous; 249} 250 251sc_actions 252sc_report_handler::force() 253{ 254 return force(SC_UNSPECIFIED); 255} 256 257 258sc_actions 259sc_report_handler::set_catch_actions(sc_actions actions) 260{ 261 sc_actions previous = sc_gem5::reportCatchActions; 262 sc_gem5::reportCatchActions = actions; 263 return previous; 264} 265 266sc_actions 267sc_report_handler::get_catch_actions() 268{ 269 return sc_gem5::reportCatchActions; 270} 271 272 273void 274sc_report_handler::set_handler(sc_report_handler_proc proc) 275{ 276 sc_gem5::reportHandlerProc = proc; 277} 278 279void 280sc_report_handler::default_handler( 281 const sc_report &report, const sc_actions &actions) 282{ 283 if (actions & SC_DISPLAY) 284 cprintf("\n%s\n", sc_report_compose_message(report)); 285 286 if ((actions & SC_LOG) && logFile) { 287 ccprintf(*logFile, "%s: %s\n", report.get_time().to_string(), 288 sc_report_compose_message(report)); 289 } 290 if (actions & SC_STOP) { 291 sc_stop_here(report.get_msg_type(), report.get_severity()); 292 sc_stop(); 293 } 294 if (actions & SC_INTERRUPT) 295 sc_interrupt_here(report.get_msg_type(), report.get_severity()); 296 if (actions & SC_ABORT) 297 sc_abort(); 298 if (actions & SC_THROW) { 299 ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 300 if (current) 301 current->isUnwinding(false); 302 throw report; 303 } 304} 305 306sc_actions 307sc_report_handler::get_new_action_id() 308{ 309 static sc_actions maxAction = SC_ABORT; 310 maxAction = maxAction << 1; 311 return maxAction; 312} 313 314sc_report * 315sc_report_handler::get_cached_report() 316{ 317 ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 318 if (current) 319 return current->lastReport(); 320 return ::sc_gem5::globalReportCache.get(); 321} 322 323void 324sc_report_handler::clear_cached_report() 325{ 326 ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 327 if (current) { 328 current->lastReport(nullptr); 329 } else { 330 ::sc_gem5::globalReportCache = nullptr; 331 } 332} 333 334bool 335sc_report_handler::set_log_file_name(const char *new_name) 336{ 337 if (!new_name) { 338 logFile = nullptr; 339 logFileName = nullptr; 340 return false; 341 } else { 342 if (logFileName) 343 return false; 344 logFileName = std::unique_ptr<std::string>(new std::string(new_name)); 345 logFile = std::unique_ptr<std::ofstream>(new std::ofstream(new_name)); 346 return true; 347 } 348} 349 350const char * 351sc_report_handler::get_log_file_name() 352{ 353 if (!logFileName) 354 return nullptr; 355 else 356 return logFileName->c_str(); 357} 358 359void 360sc_interrupt_here(const char *msg_type, sc_severity) 361{ 362 // Purposefully empty, for setting breakpoints supposedly. 363} 364 365void 366sc_stop_here(const char *msg_type, sc_severity) 367{ 368 // Purposefully empty, for setting breakpoints supposedly. 369} 370 371const std::string 372sc_report_compose_message(const sc_report &report) 373{ 374 std::ostringstream str; 375 376 const char *sevName = sc_gem5::reportSeverityNames[report.get_severity()]; 377 int id = report.get_id(); 378 379 str << sevName << ": "; 380 if (id >= 0) { 381 ccprintf(str, "(%c%d) ", sevName[0], id); 382 } 383 str << report.get_msg_type(); 384 385 const char *msg = report.get_msg(); 386 if (msg && msg[0]) 387 str << ": " << msg; 388 389 if (report.get_severity() > SC_INFO) { 390 ccprintf(str, "\nIn file: %s:%d", report.get_file_name(), 391 report.get_line_number()); 392 393 ::sc_gem5::Process *current = ::sc_gem5::scheduler.current(); 394 const char *name = report.get_process_name(); 395 if (current && sc_is_running() && name) { 396 ccprintf(str, "\nIn process: %s @ %s", name, 397 report.get_time().to_string()); 398 } 399 } 400 401 return str.str(); 402} 403 404bool 405sc_report_close_default_log() 406{ 407 if (logFile) { 408 logFile = nullptr; 409 logFileName = nullptr; 410 return false; 411 } 412 return true; 413} 414 415} // namespace sc_core 416