From 554f811247c5f16880e2edb58c39003cc74da677 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Tue, 1 Nov 2022 19:39:55 +0100 Subject: [PATCH] Display the stack of each actor during a MC replay (unless --log=no_log for the tests) --- src/kernel/actor/ActorImpl.cpp | 3 +++ src/mc/mc_base.cpp | 1 + src/mc/mc_record.cpp | 13 +++++++++++-- src/mc/mc_replay.hpp | 3 +++ src/xbt/backtrace.cpp | 19 +++++++++++++++++-- teshsuite/mc/CMakeLists.txt | 1 + .../mc/random-bug/random-bug-replay.tesh | 18 ++++++++++++++++-- 7 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/kernel/actor/ActorImpl.cpp b/src/kernel/actor/ActorImpl.cpp index 8f3b373617..e308692bd8 100644 --- a/src/kernel/actor/ActorImpl.cpp +++ b/src/kernel/actor/ActorImpl.cpp @@ -3,6 +3,7 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "src/mc/mc_replay.hpp" #include #include #include @@ -279,6 +280,8 @@ void ActorImpl::yield() if (not wannadie()) smpi_switch_data_segment(get_iface()); #endif + if (simgrid_mc_replay_show_backtraces) + xbt_backtrace_display_current(); } /** This actor will be terminated automatically when the last non-daemon actor finishes */ diff --git a/src/mc/mc_base.cpp b/src/mc/mc_base.cpp index 95965ece1e..ac3f49f346 100644 --- a/src/mc/mc_base.cpp +++ b/src/mc/mc_base.cpp @@ -19,6 +19,7 @@ #endif XBT_LOG_NEW_DEFAULT_CATEGORY(mc, "All MC categories"); +bool simgrid_mc_replay_show_backtraces = false; namespace simgrid::mc { diff --git a/src/mc/mc_record.cpp b/src/mc/mc_record.cpp index 3b35eade53..67e88835b3 100644 --- a/src/mc/mc_record.cpp +++ b/src/mc/mc_record.cpp @@ -25,6 +25,12 @@ void RecordTrace::replay() const simgrid::mc::execute_actors(); auto* engine = kernel::EngineImpl::get_instance(); + int frame_count = 1; + if (xbt_log_no_loc) + XBT_INFO("The backtrace of each transition will not be shown because of --log=no_loc"); + else + simgrid_mc_replay_show_backtraces = 1; + for (const simgrid::mc::Transition* transition : transitions_) { kernel::actor::ActorImpl* actor = engine->get_actor_by_pid(transition->aid_); xbt_assert(actor != nullptr, "Unexpected actor (id:%ld).", transition->aid_); @@ -32,8 +38,11 @@ void RecordTrace::replay() const xbt_assert(simgrid::mc::request_is_visible(simcall), "Simcall %s of actor %s is not visible.", simcall->get_cname(), actor->get_cname()); - XBT_DEBUG("Executing %ld$%i: %s", transition->aid_, transition->times_considered_, - simcall->observer_->to_string().c_str()); + XBT_INFO("***********************************************************************************"); + XBT_INFO("* Path chunk #%d '%ld/%i' Actor %s(pid:%ld): %s", frame_count++, transition->aid_, + transition->times_considered_, simcall->issuer_->get_cname(), simcall->issuer_->get_pid(), + simcall->observer_->to_string().c_str()); + XBT_INFO("***********************************************************************************"); if (not mc::actor_is_enabled(actor)) simgrid::kernel::EngineImpl::get_instance()->display_all_actor_status(); diff --git a/src/mc/mc_replay.hpp b/src/mc/mc_replay.hpp index ae8cd4a06d..7c59b5db4d 100644 --- a/src/mc/mc_replay.hpp +++ b/src/mc/mc_replay.hpp @@ -25,4 +25,7 @@ static inline int MC_record_replay_is_active() return not MC_record_path().empty(); } +/** Whether we should display extra information during this MC replay */ +extern bool simgrid_mc_replay_show_backtraces; + #endif diff --git a/src/xbt/backtrace.cpp b/src/xbt/backtrace.cpp index bead6583cc..a180720217 100644 --- a/src/xbt/backtrace.cpp +++ b/src/xbt/backtrace.cpp @@ -50,7 +50,21 @@ public: if (frame_name.rfind("simgrid::xbt::MainFunction", 0) == 0 || frame_name.rfind("simgrid::kernel::context::Context::operator()()", 0) == 0) break; - ss << " -> " << frame_count++ << "# " << frame << "\n"; + if (xbt_log_no_loc) { // Don't display file source and line if so + if (frame.name().empty()) + ss << " -> #" << frame_count++ << " (debug info not found and log:no_loc activated)\n"; + else + ss << " -> #" << frame_count++ << " " << frame.name() << "\n"; + } else + ss << " -> #" << frame_count++ << " " << frame << "\n"; + // If we are displaying the user side of a simcall, remove the crude details of context switching + if (frame_name.find("simgrid::kernel::actor::simcall_answered") != std::string::npos || + frame_name.find("simgrid::kernel::actor::simcall_blocking") != std::string::npos || + frame_name.find("simcall_run_answered") != std::string::npos || + frame_name.find("simcall_run_blocking") != std::string::npos) { + frame_count = 0; + ss.str(std::string()); // This is how you clear a stringstream in C++. clear() is something else :'( + } if (frame_name == "main") break; } else { @@ -78,7 +92,8 @@ std::string Backtrace::resolve() const void Backtrace::display() const { std::string backtrace = resolve(); - std::fprintf(stderr, "Backtrace (displayed in actor %s):\n%s\n", xbt_procname(), + std::fprintf(stderr, "Backtrace (displayed in actor %s%s):\n%s\n", xbt_procname(), + (xbt_log_no_loc ? " -- short trace because of --log=no_loc" : ""), backtrace.empty() ? "(backtrace not set -- did you install Boost.Stacktrace?)" : backtrace.c_str()); } diff --git a/teshsuite/mc/CMakeLists.txt b/teshsuite/mc/CMakeLists.txt index b4b76485e3..7d0e35197a 100644 --- a/teshsuite/mc/CMakeLists.txt +++ b/teshsuite/mc/CMakeLists.txt @@ -15,6 +15,7 @@ foreach(x dwarf dwarf-expression random-bug mutex-handling) target_link_libraries(${x} simgrid) set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x}) set_property(TARGET ${x} APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") + target_compile_options(${x} PRIVATE ${CMAKE_C_DEBUG_FLAGS}) add_dependencies(tests-mc ${x}) endif() diff --git a/teshsuite/mc/random-bug/random-bug-replay.tesh b/teshsuite/mc/random-bug/random-bug-replay.tesh index c32150f440..560b2d9253 100644 --- a/teshsuite/mc/random-bug/random-bug-replay.tesh +++ b/teshsuite/mc/random-bug/random-bug-replay.tesh @@ -1,13 +1,27 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/random-bug printf ${platfdir}/small_platform.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" "--cfg=model-check/replay:1/3;1/4" +$ ${bindir:=.}/random-bug printf ${platfdir}/small_platform.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" "--cfg=model-check/replay:1/3;1/4" --log=no_loc > [ 0.000000] (0:maestro@) Behavior: printf > [ 0.000000] (0:maestro@) path=1/3;1/4 +> [ 0.000000] (0:maestro@) The backtrace of each transition will not be shown because of --log=no_loc +> [ 0.000000] (0:maestro@) *********************************************************************************** +> [ 0.000000] (0:maestro@) * Path chunk #1 '1/3' Actor app(pid:1): Random(min:0 max:5) +> [ 0.000000] (0:maestro@) *********************************************************************************** +> [ 0.000000] (0:maestro@) *********************************************************************************** +> [ 0.000000] (0:maestro@) * Path chunk #2 '1/4' Actor app(pid:1): Random(min:0 max:5) +> [ 0.000000] (0:maestro@) *********************************************************************************** > [ 0.000000] (1:app@Fafard) Error reached > [ 0.000000] (0:maestro@) The replay of the trace is complete. The application is terminating. # Behavior: assert does not have the same output within and without MC, so don't test it here. That's already covered with the other ones ! expect signal SIGIOT -$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/random-bug abort ${platfdir}/small_platform.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" "--cfg=model-check/replay:1/3;1/4" +$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/random-bug abort ${platfdir}/small_platform.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" "--cfg=model-check/replay:1/3;1/4" --log=no_loc > [ 0.000000] (0:maestro@) Behavior: abort > [ 0.000000] (0:maestro@) path=1/3;1/4 +> [ 0.000000] (0:maestro@) The backtrace of each transition will not be shown because of --log=no_loc +> [ 0.000000] (0:maestro@) *********************************************************************************** +> [ 0.000000] (0:maestro@) * Path chunk #1 '1/3' Actor app(pid:1): Random(min:0 max:5) +> [ 0.000000] (0:maestro@) *********************************************************************************** +> [ 0.000000] (0:maestro@) *********************************************************************************** +> [ 0.000000] (0:maestro@) * Path chunk #2 '1/4' Actor app(pid:1): Random(min:0 max:5) +> [ 0.000000] (0:maestro@) *********************************************************************************** -- 2.20.1