diff --git a/projects/rocprofiler-systems/CHANGELOG.md b/projects/rocprofiler-systems/CHANGELOG.md index 564c607a29..c60f3a19ff 100644 --- a/projects/rocprofiler-systems/CHANGELOG.md +++ b/projects/rocprofiler-systems/CHANGELOG.md @@ -11,6 +11,10 @@ Full documentation for ROCm Systems Profiler is available at [https://rocm.docs. - Added a `ROCPROFSYS_PERFETTO_FLUSH_PERIOD_MS` configuration setting to set the flush period for Perfetto traces. The default value is 10000 ms (10 seconds). - Added tracing of VAAPI, MPI and host events inside `rocpd` output database. +### Changed + +- Improved Fortran main function detection to ensure `rocprof-sys-instrument` uses the Fortran program main function instead of the C wrapper. + ## ROCm Systems Profiler 1.2.0 for ROCm 7.1.0 ### Added diff --git a/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst b/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst index 52b740b106..a44dafc7d1 100644 --- a/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst +++ b/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst @@ -937,3 +937,12 @@ or library to ``/home/user``, which is where the instrumented libraries are loca patchelf --remove-rpath patchelf --set-rpath '/home/user' + +Main function detection issues +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If ROCm Systems Profiler fails to detect or instrument your program's main function, you can explicitly specify it using the ``--main-function`` (or ``-m``) option. + +.. code-block:: shell + + rocprof-sys-instrument --main-function '' -o ./foo.inst -- ./foo diff --git a/projects/rocprofiler-systems/source/bin/rocprof-sys-instrument/rocprof-sys-instrument.cpp b/projects/rocprofiler-systems/source/bin/rocprof-sys-instrument/rocprof-sys-instrument.cpp index 852473eca7..cf406c66c7 100644 --- a/projects/rocprofiler-systems/source/bin/rocprof-sys-instrument/rocprof-sys-instrument.cpp +++ b/projects/rocprofiler-systems/source/bin/rocprof-sys-instrument/rocprof-sys-instrument.cpp @@ -1703,7 +1703,28 @@ main(int argc, char** argv) // //----------------------------------------------------------------------------------// - auto* main_func = find_function(app_image, main_fname.c_str()); + procedure_t* main_func = nullptr; + // Fortran programs typically have a C-style "main" wrapper that calls the actual + // Fortran main. This should be prioritized as: + // 1. It contains the actual user code that should be instrumented and will not be + // treated as a subroutine. + // 2. If we instrument the C wrapper and if the Fortran main is written in such a way + // that Dyninst marks it with funcReturnStatus == NORETURN, then during + // rocprof-sys-run, the instrumented Fortran main will not be reached. + if(main_fname == "main") + { + // _MAIN__, MAIN__, main_, _main_, _QQmain + main_func = find_function(app_image, "^_?MAIN__|^_?main_|^_QQmain"); + } + // Note: Some Fortran compilers (e.g. Cray) may name the Fortran main function after + // the program name in the PROGRAM statement. E.g, "PROGRAM hello" becomes "hello_" + // in the disassembly. + // This is not a problem as the compiler will also generate a corresponding "main" + // symbol that has the same start address, allowing Dyninst to latch onto that. + // However, if problems persist, users should specify their main with + // "--main-function" + + if(!main_func) main_func = find_function(app_image, main_fname.c_str()); auto* user_start_func = find_function(app_image, "rocprofsys_user_start_trace", { "rocprofsys_user_start_thread_trace" }); auto* user_stop_func = find_function(app_image, "rocprofsys_user_stop_trace", @@ -1934,7 +1955,6 @@ main(int argc, char** argv) verbprintf(2, "Getting call expressions... "); - auto _init_arg0 = main_fname; if(main_func) main_sign.get(); auto main_call_args = rocprofsys_call_expr(main_sign.get());