Skip to content

Rocprofsys attach#1

Open
sputhala-amd wants to merge 22 commits into
developfrom
rocprofsys-attach
Open

Rocprofsys attach#1
sputhala-amd wants to merge 22 commits into
developfrom
rocprofsys-attach

Conversation

@sputhala-amd

@sputhala-amd sputhala-amd commented Sep 19, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Attach to a running process by PID with new CLI options (-p/--attach-pid, --attach-duration-msec), supporting manual or timed auto-detach.
    • Pre-attach mode with signal-driven attach/detach and re-attach without restarting the target.
  • Improvements
    • More robust initialization/finalization with idempotent setup and a new “Detached” runtime state.
    • Sampling offload re-initializes on re-attach to ensure consistent data capture.
  • Libraries
    • New attach library is built and installed, enabling runtime attach/detach functionality.

@coderabbitai

coderabbitai Bot commented Sep 19, 2025

Copy link
Copy Markdown

Walkthrough

Adds runtime attach/detach support. Introduces a new attach library with ptrace-based injection, environment propagation, and SIGUSR1-driven detach. Extends sample binary with attach CLI and flow. Updates core config/state, signal handling, and library lifecycle to support pre-attach mode and re-attach. Adds build integration and minor idempotency guards.

Changes

Cohort / File(s) Summary
Build integration
projects/rocprofiler-systems/source/lib/CMakeLists.txt, projects/rocprofiler-systems/source/bin/rocprof-sys-sample/CMakeLists.txt, projects/rocprofiler-systems/source/lib/rocprof-sys-attach/CMakeLists.txt
Adds rocprof-sys-attach subdir and shared library target; links sample binary against attach library; sets includes, rpaths, install rules, and flags.
Sample binary: attach CLI and flow
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp, .../rocprof-sys-sample/rocprof-sys-sample.cpp, .../rocprof-sys-sample/rocprof-sys-sample.hpp
Adds get_pid/get_attach_duration APIs, parses --attach-pid/-p and --attach-duration-msec, sets env, calls attach(), waits or prompts, then rocprofsys_detach; early-exits main when pid set.
Attach library implementation
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.hpp, .../rocprof-sys-attach/attach.cpp
Exposes C APIs: rocprofsys_attach(pid, env) and rocprofsys_detach(pid). Implements ptrace attach, env buffer creation, remote dlopen and attach, SIGUSR1 detach signaling and FIFO sync.
ptrace session
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.hpp, .../ptrace_session.cpp
Adds PTraceSession for attach/detach, remote memory ops, remote mmap/munmap, symbol resolution, remote function calls, library loading, and verbosity-controlled logging.
Core config and signals
projects/rocprofiler-systems/source/lib/core/config.hpp, .../core/config.cpp
Adds is_attach_mode(), renames is_attached()→is_mpi_attached(), adds detach signal handler registration, installs SIGUSR1 handler, introduces ROCPROFSYS_ATTACH setting, updates configure_settings(_force).
State and idempotency
projects/rocprofiler-systems/source/lib/core/state.hpp, .../core/state.cpp, .../core/perfetto.cpp
Adds State::Detached and to_string mapping; guards perfetto setup with a one-time flag.
Dynamic loader attach path
projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp
Adds load_environment_buffer and rocprofsys_dl_attach to initialize via env buffer and enable tracing when attaching.
Library lifecycle and ROCm SDK
projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp, .../library/rocprofiler-sdk.cpp, .../library/rocprofiler-sdk.hpp
Adds detach_handler, detach notification via FIFO, re-attach flows, state transitions using Detached; sdk.setup() auto-configures; adds flush() declaration.
Sampling offload re-attach
projects/rocprofiler-systems/source/lib/rocprof-sys/library/sampling.cpp
Ensures offload temp file is created/opened on re-attach and enables offloading when available.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Sample as rocprof-sys-sample
  participant AttachLib as rocprof-sys-attach.so
  participant Target as Target Process
  participant DL as librocprof-sys-dl.so

  User->>Sample: run with --attach-pid/-p [--attach-duration-msec]
  Sample->>AttachLib: rocprofsys_attach(pid, env)
  AttachLib->>Target: ptrace attach/stop
  AttachLib->>Target: mmap + write env buffer
  AttachLib->>Target: dlopen(librocprof-sys-dl.so)
  AttachLib->>DL: call rocprofsys_dl_attach(env_buf_addr)
  DL->>DL: load env, set ROCPROFSYS_ATTACH_PID
  DL->>Target: rocprofsys_init (attach mode) + enable tracing
  AttachLib->>Target: ptrace detach/continue
  alt duration > 0
    Sample-->>Sample: sleep(duration)
  else
    Sample-->>User: "Press any key to detach"
    User->>Sample: keypress
  end
  Sample->>AttachLib: rocprofsys_detach(pid)
  AttachLib->>Target: send SIGUSR1 (detach)
  Note right of Target: SIGUSR1 handled by config<br/>triggers detach_handler
  Target->>AttachLib: write byte to FIFO (/tmp/rocprofsys_detach_pipe)
  AttachLib-->>Sample: return
Loading
sequenceDiagram
  autonumber
  participant Kernel as Target (in-process)
  participant Config as core::config
  participant Lib as rocprof-sys library
  participant FIFO as /tmp/rocprofsys_detach_pipe

  Kernel->>Config: SIGUSR1 handler invoked
  Config->>Lib: detach_handler()
  alt attach mode and Active
    Lib->>Lib: finalize tooling (attach-safe)
    Lib->>FIFO: write 1 byte (detach complete)
    Lib->>Lib: set State=Detached
  else not in pre-attach
    Lib-->>Lib: no-op (message)
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

I hopped through ptrace fields tonight,
With SIGUSR1’s soft lunar light—
I stitched a pipe, a FIFO string,
To whisper “done” when kernels sing.
Now attach, detach, and hop once more—
A nimble trace at process door. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.68% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Rocprofsys attach" concisely names the primary feature added by this changeset — runtime attach/detach support for rocprofsys — and directly maps to the large set of related changes (new attach library, ptrace session, dl attach entrypoint, config/state updates, and CLI options). It is short, specific, and does not include unrelated noise. The wording is terse but sufficiently clear for a reviewer scanning PR history.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rocprofsys-attach

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 27

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp (1)

1876-1878: Call stop() before flush() to reduce lost data.

Flushing buffers before stopping contexts risks ERROR_BUFFER_BUSY and dropped records. Swap the order in tool_fini.

Apply:

-    flush();
-    stop();
+    stop();
+    flush();
projects/rocprofiler-systems/source/lib/rocprof-sys/library/sampling.cpp (2)

594-605: Use tellp() when writing; tellg() is for reads.

Writing uses _fs.write(...) but records positions via _fs.tellg(). This can return invalid positions or -1. Use tellp().

-    offload_seq_data[_seq].emplace(_fs.tellg());
+    offload_seq_data[_seq].emplace(_fs.tellp());

1179-1196: Remove offload tmp file before resetting the shared_ptr; current order skips removal.

get_offload_file().reset(); nulls the handle, so the subsequent if(get_offload_file()) never runs.

-    get_offload_file().reset();  // remove the temporary file
+    if(get_use_tmp_files())
+    {
+        auto& _f = get_offload_file();
+        if(_f) _f->remove();
+        _f.reset();
+    }
-
-    if(get_use_tmp_files() && get_offload_file())
-    {
-        get_offload_file()->remove();
-        get_offload_file().reset();
-    }
🧹 Nitpick comments (22)
projects/rocprofiler-systems/source/lib/core/state.cpp (1)

137-137: String mapping for Detached added—LGTM.

Covers the new enum; consistent with logging needs.

Consider keeping case order consistent with the enum for readability.

projects/rocprofiler-systems/source/lib/core/config.hpp (1)

51-52: Detach signal handler API addition—LGTM.

Symmetric with set_signal_handler; ensure docs mention interaction with existing handler and lifetime.

projects/rocprofiler-systems/source/lib/core/config.cpp (2)

251-252: Attach mode is derived only from ROCPROFSYS_ATTACH_PID; ignores new ROCPROFSYS_ATTACH

You add a ROCPROFSYS_ATTACH setting below, but is_attach_mode() is set solely from ROCPROFSYS_ATTACH_PID. Either honor the boolean setting here or recompute after settings load to keep behavior coherent.

Example tweak (early env + setting):

-    is_attach_mode() = tim::get_env("ROCPROFSYS_ATTACH_PID", 0) != 0;
+    // pre-attach if pid provided or explicit boolean flag set
+    const bool attach_env = tim::get_env("ROCPROFSYS_ATTACH", false, false);
+    is_attach_mode()      = attach_env || tim::get_env("ROCPROFSYS_ATTACH_PID", 0) != 0;

And/or after _config is available:

+    // re-sync after settings load
+    is_attach_mode() = is_attach_mode() || _config->get<bool>("ROCPROFSYS_ATTACH");

264-267: New setting ROCPROFSYS_ATTACH is never read

You define the setting but never consume it to influence attach behavior. Wire it into is_attach_mode() per the previous comment.

projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp (1)

907-921: Comment vs behavior mismatch: “Stop instead of shutting down” but you call shutdown

In attach mode you execute both stop() and shutdown(). Either:

  • Only stop (keep SDK client intact for re‑attach), or
  • Keep shutdown but update the comment.

If re‑attach requires full re-init anyway, prefer being explicit and skipping stop(); otherwise remove shutdown() here.

-        if(_is_attach)
-        {
-            ROCPROFSYS_VERBOSE_F(1, "Shutting down ROCm in attach mode...\n");
-            rocprofiler_sdk::stop();
-            rocprofiler_sdk::shutdown();
-        }
+        if(_is_attach)
+        {
+            ROCPROFSYS_VERBOSE_F(1, "Stopping ROCm contexts for detach...\n");
+            rocprofiler_sdk::stop();
+            // Skip shutdown in attach mode to enable faster re-attach
+        }
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.hpp (6)

1-11: Avoid heavy/OS‑specific includes in public headers

<dlfcn.h> is not used in the declarations; move it to the .cpp to reduce header surface.

-#include <dlfcn.h>

17-24: Type choices: prefer pid_t for PIDs and uintptr_t for addresses

Using size_t for PIDs/addresses may break on cross‑arch or 32/64‑bit assumptions. Consider:

  • ctor: explicit PTraceSession(pid_t);
  • address params: uintptr_t (or std::uintptr_t) instead of size_t.
-    explicit PTraceSession(size_t);
+    explicit PTraceSession(pid_t);

And for memory APIs:

-    bool write(size_t addr, const std::vector<uint8_t>& data, size_t size);
+    bool write(std::uintptr_t addr, const std::vector<uint8_t>& data, size_t size);

Apply similarly to read/swap/call_function overloads and get_pid().


35-47: Open‑ended return type for open_library

unsigned long long for handles is ambiguous. If this is an address, prefer std::uintptr_t; if a status code, use a strong typedef or enum.


58-60: Member types alignment with earlier note

const size_t pid; should align with pid_t.

-    const size_t pid;
+    const pid_t  pid;

64-72: NullBuffer overflow signature

Use the standard int_type signature to avoid surprises across libstdc++/libc++.

-class NullBuffer : public std::streambuf
-{
-public:
-    int overflow(int c) override { return c; }
-};
+class NullBuffer : public std::streambuf {
+public:
+    using int_type = std::streambuf::traits_type::int_type;
+    int_type overflow(int_type c) override { return c; }
+};

73-80: Header‑level logging macros can leak into consumers

Defining ROCPROFSYS_INFO/ERROR in a public header risks macro collisions. Prefer placing them in a private header for the attach module, or undef after use.

 #ifndef ROCPROFSYS_INFO
 #    define ROCPROFSYS_INFO                                                              \
         ((rocprofsys::attach::get_verbose() > 1) ? std::cout : rocprofsys_null_stream)
 #endif
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.cpp (1)

58-62: Propagate attach() failure and fix typo in comment.

Return the status from attach() and correct “greate”.

-    if(*(get_pid()) > 0)
+    if(*(get_pid()) > 0)
     {
-        // If the pid is greate than 0, it means we are running in the attach mode.
-        return attach(_env);
+        // If the pid is greater than 0, it means we are running in attach mode.
+        int rc = attach(_env);
+        return rc;
     }
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.cpp (2)

37-43: Remove dead code (get_dl_handle).

Unused helper can be dropped.

-void**
-get_dl_handle()
-{
-    static void* handle = nullptr;
-    return &handle;
-}

59-63: Prefer pid_t over size_t for pid parameters here and in headers.

Matches POSIX APIs (kill, ptrace). Update declarations if feasible.

projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp (1)

38-47: Optional: avoid blocking on stdin when not a TTY.

If run non-interactively, std::cin.get() blocks forever. Consider checking isatty(STDIN_FILENO) and falling back to a default timeout.

projects/rocprofiler-systems/source/lib/rocprof-sys-attach/CMakeLists.txt (3)

23-23: Do not set CMAKE_BUILD_TYPE in a subdirectory.

This overrides parent/multi-config generators. Remove this line and let the top-level or the generator control configuration.

-set(CMAKE_BUILD_TYPE "Release")

60-61: Scope debug flags to the target (and typically not PUBLIC).

-g3 on a library that’s also stripped is contradictory and leaking debug flags to dependents is undesirable. Make it PRIVATE or gate by build type.

-add_target_cxx_flag_if_avail(rocprofiler-systems-attach-library "-g3")
+# Prefer a scoped compile option:
+target_compile_options(rocprofiler-systems-attach-library PRIVATE -g3)

69-71: Library RPATH set to $ORIGIN.

Setting RPATH on a shared library can have side effects in downstream consumers. If you only need $ORIGIN for executables or tests, consider confining it there.

projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.cpp (4)

174-182: Use WUNTRACED with waitpid and check statuses.

WUNTRACED is the canonical flag; also verify WIFSTOPPED/WSTOPSIG after each waitpid.

-    if(waitpid(pid, 0, WSTOPPED) == -1)
+    if(waitpid(pid, 0, WUNTRACED) == -1)
         return false;

Also applies to: 262-270, 582-590


187-201: PAGE_SIZE is not defined here.

Use sysconf(_SC_PAGESIZE) or getpagesize() to compute length when 0.

-    newregs.rsi                     = (length == 0) ? PAGE_SIZE : length;  // length
+    const size_t page_sz            = static_cast<size_t>(sysconf(_SC_PAGESIZE));
+    newregs.rsi                     = (length == 0) ? page_sz : length;    // length

436-470: find_library(): fragile match and error handling.

  • Substring match on "library" may miss SONAME variants (e.g., libc-2.39.so). Consider matching by basename or regex.
  • If no line found, current logic may still attempt stoull (guarded by maps state, but be explicit).

13-22: Inconsistent logging macros; potential build break.

File defines ROCPROFSYS_ATTACH_LOG but uses ROCPROFSYS_INFO/ERROR streams. Ensure these are defined via a shared logging header, or add local fallbacks. Also fix printf format specifiers in logging (size_t → %zu).

Would you like a patch to introduce a lightweight fallback stream logger gated by get_verbose()?

Also applies to: 55-61, 457-459, 526-540, 544-552, 556-571

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf49039 and 185ec85.

📒 Files selected for processing (20)
  • projects/rocprofiler-systems/source/bin/rocprof-sys-sample/CMakeLists.txt (1 hunks)
  • projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp (5 hunks)
  • projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.cpp (2 hunks)
  • projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.hpp (2 hunks)
  • projects/rocprofiler-systems/source/lib/CMakeLists.txt (1 hunks)
  • projects/rocprofiler-systems/source/lib/core/config.cpp (7 hunks)
  • projects/rocprofiler-systems/source/lib/core/config.hpp (2 hunks)
  • projects/rocprofiler-systems/source/lib/core/perfetto.cpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/core/state.cpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/core/state.hpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/CMakeLists.txt (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.cpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.hpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.cpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.hpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp (3 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp (10 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.hpp (1 hunks)
  • projects/rocprofiler-systems/source/lib/rocprof-sys/library/sampling.cpp (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.cpp (1)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.cpp (4)
  • get_verbose (605-610)
  • get_verbose (606-606)
  • read (122-152)
  • read (123-123)
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.cpp (1)
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp (4)
  • get_pid (905-910)
  • get_pid (906-906)
  • attach (919-939)
  • attach (920-920)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/sampling.cpp (2)
projects/rocprofiler-systems/source/lib/core/config.cpp (2)
  • get_tmp_file (2648-2691)
  • get_tmp_file (2649-2649)
projects/rocprofiler-systems/source/lib/core/config.hpp (1)
  • get_tmp_file (399-399)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp (1)
projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp (2)
  • rocprofiler_configure (1068-1074)
  • rocprofiler_configure (1068-1070)
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp (3)
projects/rocprofiler-systems/source/bin/rocprof-sys-causal/impl.cpp (3)
  • update_env (325-368)
  • update_env (326-327)
  • update_env (948-949)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.cpp (4)
  • rocprofsys_attach (59-139)
  • rocprofsys_attach (59-59)
  • rocprofsys_detach (141-160)
  • rocprofsys_detach (141-141)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.hpp (2)
  • rocprofsys_attach (6-7)
  • rocprofsys_detach (9-9)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.cpp (1)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.hpp (15)
  • addr (27-27)
  • addr (28-28)
  • addr (30-30)
  • addr (31-31)
  • addr (32-33)
  • addr (52-52)
  • addr (53-53)
  • PTraceSession (22-22)
  • PTraceSession (23-23)
  • library (37-37)
  • library (38-39)
  • library (40-41)
  • library (42-43)
  • library (45-45)
  • library (46-46)
projects/rocprofiler-systems/source/lib/core/config.hpp (2)
projects/rocprofiler-systems/source/lib/core/config.cpp (2)
  • settings_are_configured (201-205)
  • settings_are_configured (202-202)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/thread_info.hpp (1)
  • _force (98-98)
projects/rocprofiler-systems/source/lib/core/config.cpp (5)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/thread_info.hpp (1)
  • _force (98-98)
projects/rocprofiler-systems/source/lib/core/config.hpp (2)
  • is_attach_mode (168-168)
  • get_sampling_signals (78-78)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/sampling.cpp (2)
  • block_signals (1034-1049)
  • block_signals (1035-1035)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/causal/sampling.cpp (2)
  • block_signals (550-557)
  • block_signals (551-551)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/amd_smi.cpp (2)
  • get_state (238-243)
  • get_state (239-239)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.hpp (1)
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.cpp (2)
  • PTraceSession (61-64)
  • PTraceSession (66-72)
projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp (5)
projects/rocprofiler-systems/source/lib/core/state.cpp (4)
  • get_state (67-71)
  • get_state (68-68)
  • set_state (79-93)
  • set_state (80-80)
projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp (2)
  • rocprofsys_finalize (648-670)
  • rocprofsys_finalize (648-648)
projects/rocprofiler-systems/source/lib/rocprof-sys/api.cpp (2)
  • rocprofsys_finalize (134-138)
  • rocprofsys_finalize (135-135)
projects/rocprofiler-systems/source/lib/core/config.cpp (10)
  • set_signal_handler (1282-1302)
  • set_signal_handler (1283-1283)
  • set_detach_signal_handler (1304-1324)
  • set_detach_signal_handler (1305-1305)
  • is_mpi_attached (1830-1835)
  • is_mpi_attached (1831-1831)
  • is_attach_mode (1837-1842)
  • is_attach_mode (1838-1838)
  • get_use_rocm (1940-1949)
  • get_use_rocm (1941-1941)
projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp (8)
  • setup (1898-1906)
  • setup (1899-1899)
  • start (1928-1940)
  • start (1929-1929)
  • stop (1942-1954)
  • stop (1943-1943)
  • shutdown (1908-1914)
  • shutdown (1909-1909)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: ubuntu-jammy-external-rocm (g++, ON, ON, OFF, ON, Release, OFF, ON, 6.4)
  • GitHub Check: opensuse (g++, 15.6, Release)
  • GitHub Check: opensuse (g++, 15.5, Release)
  • GitHub Check: rhel (g++, 9.3, 0.0, Release)
  • GitHub Check: rhel (g++, 9.4, 0.0, Release)
  • GitHub Check: rhel (g++, 8.10, 0.0, Release)
  • GitHub Check: ubuntu-noble (g++, ON, Release, ON, 6.3)
  • GitHub Check: ubuntu-noble (g++, ON, Release, ON, 6.4)
  • GitHub Check: ubuntu-noble (g++, ON, Release, ON, 0.0)
🔇 Additional comments (23)
projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp (1)

1558-1599: Fix dangling pointer, harden dlopen/dlsym, and don’t change public API without verification

load_environment_buffer is defined as load_environment_buffer(const char*) in projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp:1362; rocprofsys_dl_attach is a public API (declaration at dl.cpp:1405, definition at dl.cpp:1559).

  • Replace std::string{}.c_str() with nullptr in the rocprofsys_init call (dl.cpp:1558–1599) to avoid a dangling pointer.
  • Harden the librocprofiler-register path: use "librocprofiler-register.so", check dlopen() for NULL, check dlsym() before calling the symbols, log dlerror(), and dlclose() the handle on both success and failure.
  • Do not unconditionally reset rocprofsys::dl::get_inited()/get_active()/get_finied() immediately after init; either remove these resets or document explicit attach semantics and update dependent code.
  • Do NOT change rocprofsys_dl_attach signature to (const void*, size_t) unless you also change load_environment_buffer and verify/update every caller (this is a public API/ABI-impacting change).
projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.hpp (1)

54-56: New public API flush() looks good; confirm visibility/export.

Header now declares rocprofsys::rocprofiler_sdk::flush(). Implementation exists in rocprofiler-sdk.cpp. Ensure the library exports this symbol in the shared object and that downstreams don’t need extern "C".

Can you confirm the symbol appears in the built .so (e.g., nm -D | rg 'rocprofsys::rocprofiler_sdk::flush')?

projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp (1)

1900-1906: Auto‑configure on first setup—sane default; verify ROCm SDK compatibility.

Calling rocprofiler_force_configure(&rocprofiler_configure) when not initialized improves attach scenarios. Since rocprofiler_configure already self‑guards, duplicate calls are benign. Verify these APIs exist across your supported ROCm versions to avoid dlsym failures.

If you support multiple ROCm versions, please confirm availability of rocprofiler_is_initialized and rocprofiler_force_configure.

projects/rocprofiler-systems/source/lib/core/config.hpp (2)

165-169: Add deprecated alias is_attached() → is_mpi_attached()

Renaming is_attached() to is_mpi_attached() is a breaking API change — add an inline forwarding shim and deprecate the old name.

File: projects/rocprofiler-systems/source/lib/core/config.hpp (lines 165-169)

 namespace rocprofsys
 {
 // ...
 inline namespace config
 {
   // ...
- bool& is_mpi_attached();
+ bool& is_mpi_attached();
+ // Backward-compat (deprecated)
+ inline bool& is_attached() { return is_mpi_attached(); }

Search for external/public usages to plan deprecation messaging:
rg -nP '\bis_attached\b' -C2


57-58: Review _force usage in configure_settings call sites
Calls to configure_settings now include a second _force parameter defaulting to false. Existing invocations are:

  • library.cpp:466 uses (true, true)
  • library.cpp:473 uses no arguments → (true, false)
  • argparse.cpp:220 uses (false, false)
  • config.cpp (lines 109, 208) use no arguments → (true, false)

Confirm any call that should re-attach or overwrite settings explicitly passes _force = true.

projects/rocprofiler-systems/source/lib/core/state.hpp (1)

41-42: Relax set_state monotonic check to allow re‑attach from Detached → Active

State::Detached is ordered after Disabled and the current _n < get_state() check will block Detached → Active during re‑attach. Allow this limited transition by exempting specific re‑attach targets from the “no decrease” check (e.g. if cur==Detached allow _n in {PreInit, Init, Active}) and keep the existing throw for all other decreases. Location: projects/rocprofiler-systems/source/lib/core/state.cpp.

projects/rocprofiler-systems/source/lib/core/config.cpp (5)

1199-1205: Atomic storage for detach handler looks good

Using an atomic function pointer with CAS mirrors the main signal handler pattern. LGTM.


1214-1219: Exit action now honors Active state only

Reasonable guard to avoid invoking the finalization callback if activation never occurred. LGTM.

Please confirm this does not mask needed cleanup in other non‑Active states (e.g., Detached), and that upstream timemory exit paths won’t double‑deliver signals.


1304-1324: set_detach_signal_handler mirrors main handler; OK

CAS + relaxed/seq_cst fallback is consistent with the primary handler. LGTM.


1831-1841: MPI attach state split vs attach mode: fine

Separating is_mpi_attached() from is_attach_mode() clarifies semantics. LGTM.


208-213: Signature change: ensure header defaults or add zero-arg overload and update callers

Implementation at projects/rocprofiler-systems/source/lib/core/config.cpp:208–213 defines configure_settings(bool _init, bool _force); no matching header declaration was found—add default parameter values in config.hpp (e.g., bool _init = ..., bool _force = ...) or provide a zero-arg overload and update callers so the code compiles.

projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp (4)

170-172: Registering a separate detach handler is good separation of concerns

Handler slotting mirrors the exit handler. LGTM pending the signal-safety refactor.

Ensure no other code overwrites the detach handler later.


1143-1144: Skip static destruction in attach mode: good

Returning early avoids tearing down global singletons, enabling re‑attach. LGTM.


437-475: Re‑entry from Detached state: verify _once scope and re‑init safety

  • Locate the declaration of _once and confirm whether it's static/global/thread_local; ensure its lifetime/scope won't suppress intended re‑attaches across PIDs.
  • Verify repeated Init via configure_settings(true, true) is safe for thread pools, signal handlers, singletons, timers, and FDs — or ensure detach resets any one‑time guards.
  • Inspect projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp:437–475 and search the module for _once, configure_settings, and detach_handler to confirm no hidden singletons block re‑init.

560-585: ROCm attach: setup() and start() are idempotent

setup() only calls rocprofiler_force_configure when rocprofiler_is_initialized reports not-initialized (safe to call after a prior shutdown). start() iterates contexts and calls rocprofiler_start_context only for contexts where is_initialized() && !is_active(), so repeated start() calls are harmless.

Location: projects/rocprofiler-systems/source/lib/rocprof-sys/library/rocprofiler-sdk.cpp — setup() ~line 1899, shutdown() ~line 1909, start() ~line 1929, stop() ~line 1943.

projects/rocprofiler-systems/source/lib/CMakeLists.txt (1)

77-77: Add subdirectory: OK

Including rocprof-sys-attach in the build graph is expected for this feature. LGTM.

projects/rocprofiler-systems/source/bin/rocprof-sys-sample/CMakeLists.txt (1)

21-21: Link sample against attach library: OK

Private link to the new attach module is correct.

projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.cpp (1)

40-41: Parsing gate tweak looks fine.

Recognizing -p to force parse_args is reasonable.

projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.cpp (1)

118-129: Check open_library() result and bail out consistently.

Current handling is OK; no action needed beyond prior fail-fast change.

projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp (3)

359-364: Help text additions are fine.

Descriptions for attach flags are clear.


847-855: Confirm semantics: ROCPROFSYS_ATTACH_PID set to host PID, not target.

You set the env var to the controller’s PID (host), while get_pid() stores the target PID. If the target-side expects controller PID, this is correct; otherwise, set it to pid.

If the target reads ROCPROFSYS_ATTACH_PID as the target PID, change:

-            update_env(_env, "ROCPROFSYS_ATTACH_PID", getpid());  // Set to this PID
+            update_env(_env, "ROCPROFSYS_ATTACH_PID", pid);  // Set to target PID

856-866: Attach duration arg wiring looks good.

Env propagation and local state assignment are correct.

projects/rocprofiler-systems/source/lib/rocprof-sys-attach/CMakeLists.txt (1)

26-26: Visibility preset: confirm the intended value.

CMAKE_CXX_VISIBILITY_PRESET is commonly set to "hidden". "internal" is less common and may not be portable across compilers. Please confirm toolchain support or switch to "hidden" with explicit export annotations for public APIs.

Comment on lines +905 to +917
size_t*
get_pid()
{
static size_t _pid = 0;
return &_pid;
}

size_t*
get_attach_duration()
{
static size_t _v = 0;
return &_v;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use pid_t for PID storage.

Avoid size_t for PIDs.

-size_t*
+pid_t*
 get_pid()
 {
-    static size_t _pid = 0;
+    static pid_t _pid = 0;
     return &_pid;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
size_t*
get_pid()
{
static size_t _pid = 0;
return &_pid;
}
size_t*
get_attach_duration()
{
static size_t _v = 0;
return &_v;
}
pid_t*
get_pid()
{
static pid_t _pid = 0;
return &_pid;
}
size_t*
get_attach_duration()
{
static size_t _v = 0;
return &_v;
}
🤖 Prompt for AI Agents
In projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp around
lines 905–917, the PID storage uses size_t which is inappropriate; change
get_pid() to return a pointer to pid_t with a static pid_t _pid variable, update
the function signature accordingly, and include the appropriate header (e.g.,
<sys/types.h> or <unistd.h>) so pid_t is defined; leave get_attach_duration()
unchanged unless there is a separate requirement, and update any callers to
accept pid_t* instead of size_t*.

Comment on lines +919 to +939
int
attach(std::vector<char*> env)
{
rocprofsys_attach(*(get_pid()), env);
size_t ms = *(get_attach_duration());
if(!ms)
{
// Press any key to detach
std::cout << "Press any key to detach from the process with PID: " << *(get_pid())
<< std::endl;
std::cin.get();
rocprofsys_detach(*(get_pid()));
}
else
{
std::cout << "Attached. Will detach automatically in " << ms << " milliseconds\n";
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
rocprofsys_detach(*(get_pid()));
}
return 0;
} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Check attach result and short‑circuit on failure; keep types consistent.

-int
-attach(std::vector<char*> env)
+int
+attach(std::vector<char*> env)
 {
-    rocprofsys_attach(*(get_pid()), env);
-    size_t ms = *(get_attach_duration());
+    int rc = rocprofsys_attach(*(get_pid()), env);
+    if(rc != 0) return rc;
+    size_t ms = *(get_attach_duration());
     if(!ms)
     {
         // Press any key to detach
         std::cout << "Press any key to detach from the process with PID: " << *(get_pid())
                   << std::endl;
         std::cin.get();
         rocprofsys_detach(*(get_pid()));
     }
     else
     {
         std::cout << "Attached. Will detach automatically in " << ms << " milliseconds\n";
         std::this_thread::sleep_for(std::chrono::milliseconds(ms));
         rocprofsys_detach(*(get_pid()));
     }
     return 0;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
int
attach(std::vector<char*> env)
{
rocprofsys_attach(*(get_pid()), env);
size_t ms = *(get_attach_duration());
if(!ms)
{
// Press any key to detach
std::cout << "Press any key to detach from the process with PID: " << *(get_pid())
<< std::endl;
std::cin.get();
rocprofsys_detach(*(get_pid()));
}
else
{
std::cout << "Attached. Will detach automatically in " << ms << " milliseconds\n";
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
rocprofsys_detach(*(get_pid()));
}
return 0;
}
int
attach(std::vector<char*> env)
{
int rc = rocprofsys_attach(*(get_pid()), env);
if (rc != 0) return rc;
size_t ms = *(get_attach_duration());
if(!ms)
{
// Press any key to detach
std::cout << "Press any key to detach from the process with PID: " << *(get_pid())
<< std::endl;
std::cin.get();
rocprofsys_detach(*(get_pid()));
}
else
{
std::cout << "Attached. Will detach automatically in " << ms << " milliseconds\n";
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
rocprofsys_detach(*(get_pid()));
}
return 0;
}
🤖 Prompt for AI Agents
In projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp around
lines 919 to 939, capture and check the return value of rocprofsys_attach and
short‑circuit on failure (log an error and return a non‑zero exit code) instead
of always proceeding; also keep types consistent for the attach duration by
using a single unsigned integer type (e.g. uint64_t or size_t) to read
*(get_attach_duration()) and then convert/cast that value into
std::chrono::milliseconds when sleeping to avoid implicit narrowing or sign
issues.


#pragma once

#include <cstdint>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Include sys/types for pid_t instead of using size_t for PIDs.

Use pid_t for process IDs to avoid narrowing and platform mismatches.

-#include <cstdint>
+#include <cstdint>
+#include <sys/types.h>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <cstdint>
#include <cstdint>
#include <sys/types.h>
🤖 Prompt for AI Agents
In
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.hpp
around line 25, the code currently uses size_t for process IDs and only includes
<cstdint>; replace that with the proper POSIX type by adding #include
<sys/types.h> and change any PID-related declarations, parameters and return
types from size_t to pid_t (and update any related comparisons/formatting to use
pid_t-compatible types), ensuring the header compiles on platforms where pid_t
is defined.

Comment on lines +67 to +74
size_t*
get_pid();

size_t*
get_attach_duration();

int
attach(std::vector<char*> env); No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

🧩 Analysis chain

Change PID-related APIs to pid_t.

Aligns types across the attach flow and with POSIX APIs (kill, ptrace).

-size_t*
-get_pid();
+pid_t*
+get_pid();
 
-size_t*
-get_attach_duration();
+size_t*
+get_attach_duration();
 
 int
-attach(std::vector<char*> env);
+attach(std::vector<char*> env);

If attach.hpp also uses size_t pid, update it and all call sites to pid_t for consistency.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf "\n--- Show target header (first 240 lines) ---\n"
FILE="projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.hpp"
if [ -f "$FILE" ]; then
  sed -n '1,240p' "$FILE" || true
else
  echo "File not found: $FILE"
fi

printf "\n--- Searching repository for symbols: get_pid, get_attach_duration, pid_t, size_t <...> pid, attach(...) ---\n"
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden --no-ignore-vcs -S '\bget_pid\b' -C3 || true
  rg -n --hidden --no-ignore-vcs -S '\bget_attach_duration\b' -C3 || true
  rg -n --hidden --no-ignore-vcs -S '\bpid_t\b' -C3 || true
  rg -n --hidden --no-ignore-vcs -S '\bsize_t\b.*\bpid\b' -C3 || true
  rg -n --hidden --no-ignore-vcs -S 'attach\s*\(' -C3 || true
  rg -n --hidden --no-ignore-vcs -S 'size_t\s*\*\s*\w+\s*\(' -C3 || true
  rg -n --hidden --no-ignore-vcs -S 'pid_t\s*\*\s*\w+\s*\(' -C3 || true
else
  grep -RIn --line-number --exclude-dir=.git --exclude-dir=node_modules -e 'get_pid' . || true
  grep -RIn --line-number --exclude-dir=.git --exclude-dir=node_modules -e 'get_attach_duration' . || true
  grep -RIn --line-number --exclude-dir=.git --exclude-dir=node_modules -e 'pid_t' . || true
  grep -RIn --line-number --exclude-dir=.git --exclude-dir=node_modules -E 'size_t.*\bpid\b' . || true
  grep -RIn --line-number --exclude-dir=.git --exclude-dir=node_modules -e 'attach(' . || true
fi

printf "\n--- Locate any attach.hpp files ---\n"
find . -type f -iname 'attach.hpp' -print || true

printf "\n--- Summarize files referencing get_pid, get_attach_duration, or size_t <...> pid ---\n"
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden --no-ignore-vcs -S 'get_pid|get_attach_duration|\bsize_t\b.*\bpid\b' -C2 || true
else
  grep -RIn --line-number --exclude-dir=.git -E 'get_pid|get_attach_duration|size_t.*\bpid\b' . || true
fi

printf "\n--- End ---\n"

Length of output: 217046


Change PID-related APIs to pid_t.

Attach/ptrace/sample currently use size_t for PIDs — change prototypes/definitions and call sites to pid_t so they match POSIX APIs (kill/ptrace) and the rest of the codebase.

  • projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.hpp: change size_t* get_pid() → pid_t* get_pid(); (keep get_attach_duration as size_t*).
  • projects/rocprofiler-systems/source/bin/rocprof-sys-sample/impl.cpp: change static size_t _pid → static pid_t _pid and update all *(get_pid()) assignments/uses.
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.hpp & attach.cpp: change extern "C" APIs rocprofsys_attach(size_t pid, ...) and rocprofsys_detach(size_t pid) → use pid_t and update all callers.
  • projects/rocprofiler-systems/source/lib/rocprof-sys-attach/ptrace_session.hpp & ptrace_session.cpp: change PTraceSession constructor parameter, const pid member and get_pid() return type from size_t → pid_t; adjust PTRACE/kill call sites if necessary.
  • Search the attach flow for remaining size_t PID usages and update consistently; add <sys/types.h> (or equivalent) includes where required.
🤖 Prompt for AI Agents
In
projects/rocprofiler-systems/source/bin/rocprof-sys-sample/rocprof-sys-sample.hpp
lines 67-74, change the PID-related API types from size_t* to pid_t* (keep
get_attach_duration as size_t*); update the impl.cpp to make the static _pid a
pid_t and update all *(get_pid()) assignments/uses accordingly; in
projects/rocprofiler-systems/source/lib/rocprof-sys-attach/attach.hpp &
attach.cpp change extern "C" APIs to accept/return pid_t instead of size_t and
update all callers; in ptrace_session.hpp & ptrace_session.cpp change the
PTraceSession constructor parameter, the const pid member and get_pid() return
type from size_t to pid_t and adjust PTRACE/kill call sites if needed; finally
search the attach flow for any remaining size_t PID usages and replace with
pid_t and add #include <sys/types.h> (or equivalent) where required so POSIX PID
types are used consistently.

Comment on lines +1223 to +1265
// Tim: This handles signals for triggering attach/detach. It prevents the process from
// being killed at the end.
void
rocprofsys_attach_detach_action(int, siginfo_t*, void*)
{
if(!config::is_attach_mode())
{
ROCPROFSYS_BASIC_PRINT(R"(
EEEEEEEEEEEEEEEEEEEEEERRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRR OOOOOOOOO RRRRRRRRRRRRRRRRR
E::::::::::::::::::::ER::::::::::::::::R R::::::::::::::::R OO:::::::::OO R::::::::::::::::R
E::::::::::::::::::::ER::::::RRRRRR:::::R R::::::RRRRRR:::::R OO:::::::::::::OO R::::::RRRRRR:::::R
EE::::::EEEEEEEEE::::ERR:::::R R:::::RRR:::::R R:::::RO:::::::OOO:::::::ORR:::::R R:::::R
E:::::E EEEEEE R::::R R:::::R R::::R R:::::RO::::::O O::::::O R::::R R:::::R
E:::::E R::::R R:::::R R::::R R:::::RO:::::O O:::::O R::::R R:::::R
E::::::EEEEEEEEEE R::::RRRRRR:::::R R::::RRRRRR:::::R O:::::O O:::::O R::::RRRRRR:::::R
E:::::::::::::::E R:::::::::::::RR R:::::::::::::RR O:::::O O:::::O R:::::::::::::RR
E:::::::::::::::E R::::RRRRRR:::::R R::::RRRRRR:::::R O:::::O O:::::O R::::RRRRRR:::::R
E::::::EEEEEEEEEE R::::R R:::::R R::::R R:::::RO:::::O O:::::O R::::R R:::::R
E:::::E R::::R R:::::R R::::R R:::::RO:::::O O:::::O R::::R R:::::R
E:::::E EEEEEE R::::R R:::::R R::::R R:::::RO::::::O O::::::O R::::R R:::::R
EE::::::EEEEEEEE:::::ERR:::::R R:::::RRR:::::R R:::::RO:::::::OOO:::::::ORR:::::R R:::::R
E::::::::::::::::::::ER::::::R R:::::RR::::::R R:::::R OO:::::::::::::OO R::::::R R:::::R
E::::::::::::::::::::ER::::::R R:::::RR::::::R R:::::R OO:::::::::OO R::::::R R:::::R
EEEEEEEEEEEEEEEEEEEEEERRRRRRRR RRRRRRRRRRRRRRR RRRRRRR OOOOOOOOO RRRRRRRR RRRRRR

Trying to attach to an uninitialized process. Only applications launched by rocprof-sys in
pre-attach mode can be attached to.

To launch an application in pre-attach mode, either

- set env var `ROCPROFSYS_ATTACH = true` or,
- launch the process with `rocprof-sys-sample --pre-attach <OPTIONS> -- <APP> <ARGS>`

Ignoring attach attempt and continuing...
)");
return;
}
tim::signals::block_signals(get_sampling_signals(),
tim::signals::sigmask_scope::process);
auto _handler = get_detach_signal_handler().load();
if(_handler) (*_handler)();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Asynchronous signal handler does non‑async‑signal‑safe work and calls into complex code

rocprofsys_attach_detach_action:

  • prints ASCII art via logging (allocations, locks),
  • calls tim::signals::block_signals and get_sampling_signals() (non‑async‑signal‑safe),
  • invokes a user callback (get_detach_signal_handler()) which currently runs heavy logic (starts/stops tooling).

This can deadlock or crash under signal. In signal handlers, restrict to async‑signal‑safe ops (e.g., write(), sigatomic flags, self‑pipe). Recommend:

  • Replace the body with setting a volatile sig_atomic_t flag or writing a byte to a dedicated eventfd/self‑pipe.
  • Handle the actual attach/detach work on a normal thread (e.g., a small monitor thread created in configure_signal_handler or reuse an existing runtime loop).

I can draft a self‑pipe + monitor thread patch if desired.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== locating rocprofsys_attach_detach_action ==="
rg -n --hidden --no-ignore-vcs "rocprofsys_attach_detach_action" -S || true

FILE=$(rg --hidden --no-ignore-vcs "rocprofsys_attach_detach_action" -S --files-with-matches | head -n1 || true)
if [ -n "$FILE" ]; then
  echo "=== printing $FILE (1180-1280) ==="
  sed -n '1180,1280p' "$FILE" || true
else
  echo "Function definition file not found."
fi

echo "=== searching related symbols ==="
rg -n --hidden --no-ignore-vcs "get_detach_signal_handler" -S -C3 || true
rg -n --hidden --no-ignore-vcs "set_detach_signal_handler" -S -C3 || true
rg -n --hidden --no-ignore-vcs "get_sampling_signals" -S -C3 || true
rg -n --hidden --no-ignore-vcs "tim::signals::block_signals" -S -C3 || true
rg -n --hidden --no-ignore-vcs "configure_signal_handler" -S -C3 || true
rg -n --hidden --no-ignore-vcs "sigaction" -S -C3 || true
rg -n --hidden --no-ignore-vcs "sa_sigaction" -S -C3 || true
rg -n --hidden --no-ignore-vcs "signal(" -S -C3 || true

echo "=== done ==="

Length of output: 75518


Critical: unsafe SIG handler — remove non‑async‑signal‑unsafe work from rocprofsys_attach_detach_action

rocprofsys_attach_detach_action (projects/rocprofiler-systems/source/lib/core/config.cpp:1226–1264) performs non‑async‑signal‑safe operations (ROCPROFSYS_BASIC_PRINT — allocs/locks, tim::signals::block_signals(get_sampling_signals()) — non‑async‑safe, and invoking the callback from get_detach_signal_handler() which runs heavy tooling). It is installed as sa_sigaction for DETACH_SIG in configure_signal_handler (config.cpp:1367–1372).

  • Fix: replace the handler body with an async‑safe notifier (volatile sig_atomic_t flag or write a byte to a dedicated self‑pipe/eventfd); do all attach/detach work on a normal thread (monitor thread created in configure_signal_handler or reuse an existing runtime loop).
  • Review rocprofsys_exit_action (config.cpp:1206–1216) for similar issues.
🤖 Prompt for AI Agents
projects/rocprofiler-systems/source/lib/core/config.cpp lines 1223-1265: the SIG
handler rocprofsys_attach_detach_action performs non-async-signal-safe
operations (printing, blocking signals, invoking heavy callbacks); change it to
a minimal async-safe notifier only (set a volatile sig_atomic_t flag or write a
byte to a self-pipe/eventfd) and return immediately; then, in
configure_signal_handler create or reuse a monitor thread/loop that polls the
flag or reads the pipe/eventfd and performs the existing attach/detach work
(ROCPROFSYS_BASIC_PRINT, tim::signals::block_signals, calling the detach
handler) from the normal thread context; also update signal installation to use
the new minimal handler and similarly review/fix rocprofsys_exit_action (around
lines ~1206-1216) to follow the same pattern.

Comment on lines +1361 to +1389
void
load_environment_buffer(const char* environment_buffer)
{
// Environment_buffer is a null-character delimited list of name value pairs.
// Each name and value is delimited separately.
// The first 4 bytes contain an uint32_t count of pairs

if(!environment_buffer)
{
ROCPROFSYS_DL_LOG(1, "Attachment was invoked with no environment variables "
"provided for what to trace.");
return;
}

const uint32_t pair_count = *reinterpret_cast<const uint32_t*>(environment_buffer);
const char* position = environment_buffer + sizeof(uint32_t);
for(uint32_t pair_idx = 0; pair_idx < pair_count; ++pair_idx)
{
const char* name = position;
position += strlen(name) + 1;
const char* value = position;
position += strlen(value) + 1;

ROCPROFSYS_DL_LOG(2, "Attachment adding environment variable: %s=%s\n", name,
value);
setenv(name, value, 1);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix unbounded and potentially unaligned parsing of env buffer (OOB/UB risk).

The function trusts an attacker-controlled pointer with no length. It:

  • Reinterprets an unaligned char buffer as uint32_t (UB on some archs).
  • Uses strlen in a loop without any upper bound, enabling out-of-bounds reads and crashes if the buffer is malformed.
  • Lacks validation against an overall buffer size.

Recommend: make the parser length-aware, copy the count via memcpy, and use strnlen with a remaining counter. Also, prefer allowing only ROCPROFSYS_* variables. Add and includes if not already present.

Apply this diff to harden the parser (paired with signature changes below):

-void
-load_environment_buffer(const char* environment_buffer)
+void
+load_environment_buffer(const void* environment_buffer, size_t buffer_len)
 {
-    // Environment_buffer is a null-character delimited list of name value pairs.
-    // Each name and value is delimited separately.
-    // The first 4 bytes contain an uint32_t count of pairs
-
-    if(!environment_buffer)
-    {
-        ROCPROFSYS_DL_LOG(1, "Attachment was invoked with no environment variables "
-                             "provided for what to trace.");
-        return;
-    }
-
-    const uint32_t pair_count = *reinterpret_cast<const uint32_t*>(environment_buffer);
-    const char*    position   = environment_buffer + sizeof(uint32_t);
-    for(uint32_t pair_idx = 0; pair_idx < pair_count; ++pair_idx)
-    {
-        const char* name = position;
-        position += strlen(name) + 1;
-        const char* value = position;
-        position += strlen(value) + 1;
-
-        ROCPROFSYS_DL_LOG(2, "Attachment adding environment variable: %s=%s\n", name,
-                          value);
-        setenv(name, value, 1);
-    }
+    // Environment_buffer format:
+    // [uint32_t pair_count][name'\0'][value'\0']... (repeated pair_count times)
+    if(!environment_buffer || buffer_len < sizeof(uint32_t))
+    {
+        ROCPROFSYS_DL_LOG(1, "Attachment invoked with no/short environment buffer.\n");
+        return;
+    }
+
+    uint32_t pair_count = 0;
+    std::memcpy(&pair_count, environment_buffer, sizeof(uint32_t));
+
+    const unsigned char* pos = static_cast<const unsigned char*>(environment_buffer) + sizeof(uint32_t);
+    size_t               rem = buffer_len - sizeof(uint32_t);
+
+    // soft cap to avoid pathological inputs
+    const uint32_t kMaxPairs = 1024;
+    if(pair_count > kMaxPairs) pair_count = kMaxPairs;
+
+    for(uint32_t i = 0; i < pair_count; ++i)
+    {
+        size_t name_len = strnlen(reinterpret_cast<const char*>(pos), rem);
+        if(name_len >= rem) { ROCPROFSYS_DL_LOG(0, "Malformed env buffer (name).\n"); return; }
+        const char* name = reinterpret_cast<const char*>(pos);
+        pos += name_len + 1; rem -= name_len + 1;
+
+        size_t val_len = strnlen(reinterpret_cast<const char*>(pos), rem);
+        if(val_len >= rem) { ROCPROFSYS_DL_LOG(0, "Malformed env buffer (value).\n"); return; }
+        const char* value = reinterpret_cast<const char*>(pos);
+        pos += val_len + 1; rem -= val_len + 1;
+
+        // optionally: restrict to "ROCPROFSYS_*"
+        // if(strncmp(name, "ROCPROFSYS_", 11) != 0) continue;
+
+        ROCPROFSYS_DL_LOG(2, "Attachment adding environment variable: %s=%s\n", name, value);
+        setenv(name, value, 1);
+    }
 }

Outside this hunk: please add the required headers near the top of the file:

  • #include
  • #include
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void
load_environment_buffer(const char* environment_buffer)
{
// Environment_buffer is a null-character delimited list of name value pairs.
// Each name and value is delimited separately.
// The first 4 bytes contain an uint32_t count of pairs
if(!environment_buffer)
{
ROCPROFSYS_DL_LOG(1, "Attachment was invoked with no environment variables "
"provided for what to trace.");
return;
}
const uint32_t pair_count = *reinterpret_cast<const uint32_t*>(environment_buffer);
const char* position = environment_buffer + sizeof(uint32_t);
for(uint32_t pair_idx = 0; pair_idx < pair_count; ++pair_idx)
{
const char* name = position;
position += strlen(name) + 1;
const char* value = position;
position += strlen(value) + 1;
ROCPROFSYS_DL_LOG(2, "Attachment adding environment variable: %s=%s\n", name,
value);
setenv(name, value, 1);
}
}
void
load_environment_buffer(const void* environment_buffer, size_t buffer_len)
{
// Environment_buffer format:
// [uint32_t pair_count][name'\0'][value'\0']... (repeated pair_count times)
if(!environment_buffer || buffer_len < sizeof(uint32_t))
{
ROCPROFSYS_DL_LOG(1, "Attachment invoked with no/short environment buffer.\n");
return;
}
uint32_t pair_count = 0;
std::memcpy(&pair_count, environment_buffer, sizeof(uint32_t));
const unsigned char* pos = static_cast<const unsigned char*>(environment_buffer) + sizeof(uint32_t);
size_t rem = buffer_len - sizeof(uint32_t);
// soft cap to avoid pathological inputs
const uint32_t kMaxPairs = 1024;
if(pair_count > kMaxPairs) pair_count = kMaxPairs;
for(uint32_t i = 0; i < pair_count; ++i)
{
size_t name_len = strnlen(reinterpret_cast<const char*>(pos), rem);
if(name_len >= rem) { ROCPROFSYS_DL_LOG(0, "Malformed env buffer (name).\n"); return; }
const char* name = reinterpret_cast<const char*>(pos);
pos += name_len + 1; rem -= name_len + 1;
size_t val_len = strnlen(reinterpret_cast<const char*>(pos), rem);
if(val_len >= rem) { ROCPROFSYS_DL_LOG(0, "Malformed env buffer (value).\n"); return; }
const char* value = reinterpret_cast<const char*>(pos);
pos += val_len + 1; rem -= val_len + 1;
// optionally: restrict to "ROCPROFSYS_*"
// if(strncmp(name, "ROCPROFSYS_", 11) != 0) continue;
ROCPROFSYS_DL_LOG(2, "Attachment adding environment variable: %s=%s\n", name, value);
setenv(name, value, 1);
}
}

Comment on lines +1405 to +1406
int rocprofsys_dl_attach(const char* env_buff) ROCPROFSYS_PUBLIC_API;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Public API should carry buffer length for safe parsing.

Expose the length in the new API. This is a new symbol; best to get it right now.

-    int rocprofsys_dl_attach(const char* env_buff) ROCPROFSYS_PUBLIC_API;
+    int rocprofsys_dl_attach(const void* env_buff, size_t env_len) ROCPROFSYS_PUBLIC_API;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
int rocprofsys_dl_attach(const char* env_buff) ROCPROFSYS_PUBLIC_API;
int rocprofsys_dl_attach(const void* env_buff, size_t env_len) ROCPROFSYS_PUBLIC_API;
🤖 Prompt for AI Agents
In projects/rocprofiler-systems/source/lib/rocprof-sys-dl/dl.cpp around lines
1405-1406, the public API rocprofsys_dl_attach(const char* env_buff) must accept
a buffer length to avoid unsafe parsing; change the declaration to include a
size_t/env_buff_len parameter, update the corresponding implementation and any
internal helpers to use the provided length instead of relying on
NUL-termination, update all callers to pass the buffer length, bump the API
symbol/version as appropriate (new symbol), and update any header(s) and API
docs/tests to reflect the new signature.

Comment on lines +151 to 164
// Tim: Handles attach/detach. This replaces finalization handler if dl in initialized in
// attach mode.
void
detach_handler()
{
if(get_state() < State::Active)
{
ROCPROFSYS_VERBOSE_F(1, "ATTACH ACTIVE\n");
rocprofsys_init_tooling_hidden();
return;
}
rocprofsys_finalize();
}
auto

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

detach_handler runs heavy logic in signal context

This is invoked from the SA_SIGINFO handler via get_detach_signal_handler(). It calls rocprofsys_init_tooling_hidden()/rocprofsys_finalize(), both far beyond async‑signal‑safe scope. This risks deadlocks and undefined behavior.

  • Convert the signal path to a notifier (sigatomic flag or self‑pipe).
  • Move this function’s body to a normal thread that reacts to the notification.
    I can provide a self‑pipe monitor integrated with ensure_finalization() on request.

Comment on lines +1115 to +1138
if(_is_attach)
{
// Send signal to controller to finish cleaning up
const char* NOTIFY_PIPE_PATH = "/tmp/rocprofsys_detach_pipe"; // Hardcoded path
int pipe_fd = open(NOTIFY_PIPE_PATH, O_WRONLY);
if(pipe_fd != -1)
{
ssize_t bytes =
write(pipe_fd, "D", 1); // Write one byte to unblock the controller
if(bytes == -1)
{
ROCPROFSYS_VERBOSE_F(0, "Failed to write to detach confirmation pipe");
}
close(pipe_fd);
}
else
{
// Log an error if possible
fprintf(stderr, "[TARGET ERROR] Could not open notify pipe.\n");
}
set_state(State::Detached);
ROCPROFSYS_VERBOSE_F(1, "Resuming normal execution.\n");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Hardcoded FIFO path under /tmp is unsafe and brittle

/tmp/rocprofsys_detach_pipe is vulnerable to TOCTOU/symlink issues and cross‑user collisions. Use an env‑provided path, validate it’s a FIFO, and open with O_NOFOLLOW|O_CLOEXEC.

-        const char* NOTIFY_PIPE_PATH = "/tmp/rocprofsys_detach_pipe";  // Hardcoded path
-        int         pipe_fd          = open(NOTIFY_PIPE_PATH, O_WRONLY);
+        const char* envp = getenv("ROCPROFSYS_DETACH_PIPE");
+        const char* NOTIFY_PIPE_PATH = (envp && *envp) ? envp : nullptr;
+        if(!NOTIFY_PIPE_PATH) {
+            ROCPROFSYS_VERBOSE_F(0, "No detach notify pipe specified (ROCPROFSYS_DETACH_PIPE unset)\n");
+        }
+        int pipe_fd = (NOTIFY_PIPE_PATH) ? open(NOTIFY_PIPE_PATH, O_WRONLY | O_CLOEXEC | O_NOFOLLOW) : -1;
         if(pipe_fd != -1)
         {
+            struct stat st{};
+            if(fstat(pipe_fd, &st) == 0 && S_ISFIFO(st.st_mode)) {
             ssize_t bytes =
                 write(pipe_fd, "D", 1);  // Write one byte to unblock the controller
             if(bytes == -1)
             {
                 ROCPROFSYS_VERBOSE_F(0, "Failed to write to detach confirmation pipe");
             }
             close(pipe_fd);
+            } else {
+                ROCPROFSYS_VERBOSE_F(0, "Notify path is not a FIFO\n");
+                close(pipe_fd);
+            }
         }
         else
         {
             // Log an error if possible
             fprintf(stderr, "[TARGET ERROR] Could not open notify pipe.\n");
         }

Also consider a per‑session unique path (e.g., include PID) created by the controller with 0600 perms.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(_is_attach)
{
// Send signal to controller to finish cleaning up
const char* NOTIFY_PIPE_PATH = "/tmp/rocprofsys_detach_pipe"; // Hardcoded path
int pipe_fd = open(NOTIFY_PIPE_PATH, O_WRONLY);
if(pipe_fd != -1)
{
ssize_t bytes =
write(pipe_fd, "D", 1); // Write one byte to unblock the controller
if(bytes == -1)
{
ROCPROFSYS_VERBOSE_F(0, "Failed to write to detach confirmation pipe");
}
close(pipe_fd);
}
else
{
// Log an error if possible
fprintf(stderr, "[TARGET ERROR] Could not open notify pipe.\n");
}
set_state(State::Detached);
ROCPROFSYS_VERBOSE_F(1, "Resuming normal execution.\n");
}
if(_is_attach)
{
// Send signal to controller to finish cleaning up
const char* envp = getenv("ROCPROFSYS_DETACH_PIPE");
const char* NOTIFY_PIPE_PATH = (envp && *envp) ? envp : nullptr;
if(!NOTIFY_PIPE_PATH) {
ROCPROFSYS_VERBOSE_F(0, "No detach notify pipe specified (ROCPROFSYS_DETACH_PIPE unset)\n");
}
int pipe_fd = (NOTIFY_PIPE_PATH) ? open(NOTIFY_PIPE_PATH, O_WRONLY | O_CLOEXEC | O_NOFOLLOW) : -1;
if(pipe_fd != -1)
{
struct stat st{};
if(fstat(pipe_fd, &st) == 0 && S_ISFIFO(st.st_mode)) {
ssize_t bytes =
write(pipe_fd, "D", 1); // Write one byte to unblock the controller
if(bytes == -1)
{
ROCPROFSYS_VERBOSE_F(0, "Failed to write to detach confirmation pipe");
}
close(pipe_fd);
} else {
ROCPROFSYS_VERBOSE_F(0, "Notify path is not a FIFO\n");
close(pipe_fd);
}
}
else
{
// Log an error if possible
fprintf(stderr, "[TARGET ERROR] Could not open notify pipe.\n");
}
set_state(State::Detached);
ROCPROFSYS_VERBOSE_F(1, "Resuming normal execution.\n");
}
🤖 Prompt for AI Agents
In projects/rocprofiler-systems/source/lib/rocprof-sys/library.cpp around lines
1115-1138, replace the hardcoded "/tmp/rocprofsys_detach_pipe" usage with an
environment- or controller-supplied path (fallback to a safe default only if
unavoidable); before opening, validate the path length and sanitize input, then
open the file with O_WRONLY | O_NOFOLLOW | O_CLOEXEC and check the resulting fd;
immediately fstat the fd and verify S_ISFIFO(st_mode) (and optionally that
st_mode & 0177 == 0 or permission bits match 0600) to avoid symlink/TOCTOU and
cross-user issues; handle all error cases with clear logging, do the single-byte
write if the checks pass, and prefer a per-session unique FIFO name (e.g.,
include controller PID or session id created by the controller with 0600 perms)
rather than a global /tmp filename.

Comment on lines +825 to +839
if(!_file)
{
// Initialize the offload file. This is necessary in the case of re-attach
auto& _tmp_v = get_offload_file();
_tmp_v = config::get_tmp_file("sampling");
auto _success = _tmp_v->open();
ROCPROFSYS_CI_FAIL(!_success,
"Error opening sampling offload temporary file '%s'\n",
_tmp_v->filename.c_str());
}
if(_file && *_file)
{
// Ensure that the offload file is open
_sampler->set_offload(&offload_buffer);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix re-attach offload init: update local handle, clear stale positions, and avoid noop condition.

  • _file is not updated after reinitializing get_offload_file(), so set_offload() may never be enabled on re-attach.
  • Old offload_seq_data positions persist across runs and will point into a new file (corruption risk).
  • Trailing }; after the block is a stray semicolon.

Apply:

-            auto _file = get_offload_file();
-            if(!_file)
-            {
-                // Initialize the offload file. This is necessary in the case of re-attach
-                auto& _tmp_v  = get_offload_file();
-                _tmp_v        = config::get_tmp_file("sampling");
-                auto _success = _tmp_v->open();
-                ROCPROFSYS_CI_FAIL(!_success,
-                                   "Error opening sampling offload temporary file '%s'\n",
-                                   _tmp_v->filename.c_str());
-            }
-            if(_file && *_file)
-            {
-                // Ensure that the offload file is open
-                _sampler->set_offload(&offload_buffer);
-            };
+            auto _file = get_offload_file();
+            if(!_file)
+            {
+                // Initialize the offload file for re-attach
+                auto& _of = get_offload_file();
+                _of       = config::get_tmp_file("sampling");
+                auto ok   = _of->open();
+                ROCPROFSYS_CI_FAIL(!ok,
+                                   "Error opening sampling offload temporary file '%s'\n",
+                                   _of->filename.c_str());
+                // stale offsets from prior runs are invalid for a new file
+                offload_seq_data.clear();
+                _file = _of;
+            }
+            if(_file && _file->stream.is_open())
+            {
+                _sampler->set_offload(&offload_buffer);
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(!_file)
{
// Initialize the offload file. This is necessary in the case of re-attach
auto& _tmp_v = get_offload_file();
_tmp_v = config::get_tmp_file("sampling");
auto _success = _tmp_v->open();
ROCPROFSYS_CI_FAIL(!_success,
"Error opening sampling offload temporary file '%s'\n",
_tmp_v->filename.c_str());
}
if(_file && *_file)
{
// Ensure that the offload file is open
_sampler->set_offload(&offload_buffer);
};
auto _file = get_offload_file();
if(!_file)
{
// Initialize the offload file for re-attach
auto& _of = get_offload_file();
_of = config::get_tmp_file("sampling");
auto ok = _of->open();
ROCPROFSYS_CI_FAIL(!ok,
"Error opening sampling offload temporary file '%s'\n",
_of->filename.c_str());
// stale offsets from prior runs are invalid for a new file
offload_seq_data.clear();
_file = _of;
}
if(_file && _file->stream.is_open())
{
_sampler->set_offload(&offload_buffer);
}
🤖 Prompt for AI Agents
In projects/rocprofiler-systems/source/lib/rocprof-sys/library/sampling.cpp
around lines 825-839, the re-attach path doesn't update the local _file handle
after recreating the offload file, leaves stale offload_seq_data positions from
a prior file, and contains a stray trailing semicolon; to fix, after assigning
get_offload_file() to the temporary (_tmp_v) update the local _file to point at
the new file handle so subsequent checks succeed, reset/clear any persistent
offload position/state (e.g., zero or clear offload_seq_data/offload_buffer
position indexes) so they don't reference offsets in the new file, ensure
set_offload(&offload_buffer) is called when the file is open, and remove the
trailing stray semicolon from the closing block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants