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