diff --git a/src/apex/address_resolution.cpp b/src/apex/address_resolution.cpp index 87780c0e..795bb82b 100644 --- a/src/apex/address_resolution.cpp +++ b/src/apex/address_resolution.cpp @@ -118,8 +118,16 @@ namespace apex { if (rc == 0) { } else { node->info.probeAddr = ip; - node->info.filename = strdup(info.dli_fname); - node->info.funcname = strdup(info.dli_sname); + if (info.dli_fname == nullptr) { + node->info.filename = strdup("unknown"); + } else { + node->info.filename = strdup(info.dli_fname); + } + if (info.dli_sname == nullptr) { + node->info.funcname = strdup("unknown"); + } else { + node->info.funcname = strdup(info.dli_sname); + } } #endif // no APEX_HAVE_BFD #endif // no __APPLE__ diff --git a/src/apex/apex.cpp b/src/apex/apex.cpp index f3066179..100e775f 100644 --- a/src/apex/apex.cpp +++ b/src/apex/apex.cpp @@ -114,7 +114,7 @@ using namespace std; namespace apex { -bool& apex::get_program_over() { +bool& get_program_over() { static bool _program_over{false}; return _program_over; } @@ -671,7 +671,7 @@ inline std::shared_ptr _new_task( } void debug_print(const char * event, std::shared_ptr tt_ptr) { - if (apex::get_program_over()) return; + if (get_program_over()) return; static std::mutex this_mutex; std::unique_lock l(this_mutex); std::stringstream ss; @@ -877,6 +877,7 @@ void start(std::shared_ptr tt_ptr) { return; } } + tt_ptr->prof->thread_id = thread_instance::instance().get_id(); // If we are allowing untied timers, clear the timer stack on this thread if (apex_options::untied_timers() == true) { thread_instance::instance().clear_current_profiler(); @@ -1833,7 +1834,7 @@ void finalize(void) void cleanup(void) { in_apex prevent_deadlocks; FUNCTION_ENTER - apex::get_program_over() = true; + get_program_over() = true; #ifdef APEX_HAVE_HPX // prevent crash at shutdown. return; diff --git a/src/apex/apex_api.hpp b/src/apex/apex_api.hpp index 992f5a6e..2783e95a 100644 --- a/src/apex/apex_api.hpp +++ b/src/apex/apex_api.hpp @@ -357,6 +357,11 @@ APEX_EXPORT std::shared_ptr new_task( const uint64_t task_id = UINTMAX_MAX, const std::shared_ptr parent_task = null_task_wrapper); +APEX_EXPORT std::shared_ptr new_task( + const std::string &name, + const uint64_t task_id = UINTMAX_MAX, + const std::vector> parent_tasks); + /** \brief Create a new task (dependency). @@ -856,6 +861,8 @@ APEX_EXPORT void send (uint64_t tag, uint64_t size, uint64_t target); APEX_EXPORT void recv (uint64_t tag, uint64_t size, uint64_t source_rank, uint64_t source_thread); +APEX_EXPORT bool& get_program_over(void); + /** \brief A convenience class for using APEX in C++ applications. diff --git a/src/apex/profiler.hpp b/src/apex/profiler.hpp index 4f35ae9b..21eb163e 100644 --- a/src/apex/profiler.hpp +++ b/src/apex/profiler.hpp @@ -86,7 +86,8 @@ class profiler { guid(task->guid), is_counter(false), is_resume(resume), - is_reset(reset), stopped(false) { + is_reset(reset), stopped(false), + thread_id(task->thread_id) { task->prof = this; task->start_ns = start_ns; } diff --git a/src/apex/taskstubs_implementation.cpp b/src/apex/taskstubs_implementation.cpp index 65512af6..8658f9b0 100644 --- a/src/apex/taskstubs_implementation.cpp +++ b/src/apex/taskstubs_implementation.cpp @@ -74,6 +74,8 @@ extern "C" { const tasktimer_guid_t timer_guid, const tasktimer_guid_t* parent_guids, const uint64_t parent_count) { + static bool& over = apex::get_program_over(); + if (over) return nullptr; // TODO: need to handle multiple parents! // need to look up the parent shared pointers? std::vector> parent_tasks; @@ -110,6 +112,8 @@ extern "C" { tasktimer_timer_t timer, tasktimer_argument_value_p arguments, uint64_t argument_count) { + static bool& over = apex::get_program_over(); + if (over) return; // TODO: handle the schedule event, somehow APEX_UNUSED(timer); APEX_UNUSED(arguments); @@ -117,6 +121,8 @@ extern "C" { } #define MAP_TASK(_timer, _apex_timer) \ + static bool& over_{apex::get_program_over()}; \ + if (over_) return; \ uint64_t _tmp = (uint64_t)(_timer); \ auto _apex_timer = safeLookup(_tmp); @@ -129,6 +135,8 @@ extern "C" { } void tasktimer_yield_impl( tasktimer_timer_t timer) { + static bool& over = apex::get_program_over(); + if (over) return; MAP_TASK(timer, apex_timer); apex::yield(apex_timer); } @@ -170,5 +178,46 @@ extern "C" { APEX_UNUSED(children); APEX_UNUSED(child_count); } + + void timerStack( + std::shared_ptr apex_timer, + bool start) { + static thread_local std::stack> theStack; + if (start) { + apex::start(apex_timer); + theStack.push(apex_timer); + } else { + auto timer = theStack.top(); + apex::stop(timer); + theStack.pop(); + } + } + + void tasktimer_data_transfer_start_impl( + tasktimer_guid_t guid, + tasktimer_execution_space_p source_type, + const char* source_name, + const void* source_ptr, + tasktimer_execution_space_p dest_type, + const char* dest_name, + const void* dest_ptr) { + std::shared_ptr parent = safeLookup(guid); + auto task = apex::new_task("data xfer", 0, parent); + timerStack(task, true); + } + + void tasktimer_data_transfer_stop_impl(tasktimer_guid_t guid) { + timerStack(nullptr, false); + } + + void tasktimer_command_start_impl(const char* type_name) { + auto task = apex::new_task(type_name); + timerStack(task, true); + } + + void tasktimer_command_stop_impl(void) { + timerStack(nullptr, false); + } + } diff --git a/src/apex/thread_instance.cpp b/src/apex/thread_instance.cpp index 25e8bee1..035923c3 100644 --- a/src/apex/thread_instance.cpp +++ b/src/apex/thread_instance.cpp @@ -88,7 +88,7 @@ thread_instance::~thread_instance(void) { } std::cout << "thread " << _id << " exiting... " << __APEX_FUNCTION__ << std::endl; } - if (apex::get_program_over()) { return; } + if (get_program_over()) { return; } if (_top_level_timer != nullptr) { stop(_top_level_timer); _top_level_timer = nullptr; diff --git a/src/apex/trace_event_listener.cpp b/src/apex/trace_event_listener.cpp index 5506e2cf..214e46ff 100644 --- a/src/apex/trace_event_listener.cpp +++ b/src/apex/trace_event_listener.cpp @@ -198,11 +198,13 @@ void write_flow_event(std::stringstream& ss, double ts, char ph, inline void trace_event_listener::_common_stop(std::shared_ptr &p) { static APEX_NATIVE_TLS long unsigned int tid = get_thread_id_metadata(); + static auto main_wrapper = task_wrapper::get_apex_main_wrapper(); // With HPX, the APEX MAIN timer will be stopped on a different thread // than the one that started it. So... make sure we get the right TID // But don't worry, the thread metadata will have been written at the // event start. - long unsigned int _tid = (p->tt_ptr->explicit_trace_start ? p->thread_id : tid); + //long unsigned int _tid = (p->tt_ptr->explicit_trace_start ? p->thread_id : tid); + long unsigned int _tid = p->thread_id; if (!_terminate) { std::stringstream ss; ss.precision(3); @@ -212,7 +214,8 @@ inline void trace_event_listener::_common_stop(std::shared_ptr &p) { pguid = p->tt_ptr->parent->guid; } // if the parent tid is not the same, create a flow event BEFORE the single event - if (p->tt_ptr->parent != nullptr + if (p->tt_ptr->parent != nullptr && + p->tt_ptr->parent != main_wrapper #ifndef APEX_HAVE_HPX // ...except for HPX - make the flow event regardless && p->tt_ptr->parent->thread_id != _tid #endif diff --git a/src/scripts/apex_exec b/src/scripts/apex_exec index 4341c07d..e8b49781 100755 --- a/src/scripts/apex_exec +++ b/src/scripts/apex_exec @@ -29,6 +29,7 @@ $(basename "$0") executable where APEX options are zero or more of: --apex:help show this usage message --apex:debug run with APEX in debugger + --apex:debugger debugger executable name (default: gdb) --apex:verbose enable verbose list of APEX environment variables --apex:screen enable screen text output (on by default) --apex:screen-detail enable detailed text output (off by default) @@ -185,6 +186,9 @@ while (( "$#" )); do ;; --apex:debug) debug=yes + if [ "$debugger" == "" ] ; then + debugger=gdb + fi shift ;; --apex:pthread) @@ -422,6 +426,16 @@ while (( "$#" )); do postprocess=yes shift ;; + --apex:debugger) + debug=yes + if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then + debugger=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + usage + fi + ;; --apex:concur_max|--apex:concur-max) if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then export APEX_MEASURE_CONCURRENCY_MAX_TIMERS=$2 @@ -710,11 +724,7 @@ else gdbargs="-batch -q" fi #echo "set env LD_AUDIT=${APEX_LD_AUDIT}" >> ./.gdbcmds - if [ $hip = yes ] ; then - debugger="rocgdb -x ${gdbcmds} ${gdbargs} --args" - else - debugger="gdb -x ${gdbcmds} ${gdbargs} --args" - fi + debugger="${debugger} -x ${gdbcmds} ${gdbargs} --args" else export LD_LIBRARY_PATH=${APEX_LD_LIBRARY_PATH} export LD_PRELOAD=${APEX_LD_PRELOAD}