Files
rocm-systems/projects/hip-tests/catch/unit/errorHandling/OutCapture.hh
T
Karthik Jayaprakash 99c3a06f4e SWDEV-549518 - Enable logging dynamically through HIP APIS. (#1079)
* SWDEV-549518 - Enable logging dynamically through HIP APIS.

* SWDEV-549518 - Adding ROCProfiler related new API changes.

* rocprofiler-sdk changes for hip api additions.

---------

Co-authored-by: Venkateshwar Reddy Kandula <venkateshwar.kandula1306@gmail.com>
Co-authored-by: jainprad <92369414+jainprad@users.noreply.github.com>
2026-01-19 16:16:14 -05:00

135 lines
4.1 KiB
C++

/*
Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#pragma once
#include <iostream>
#include <sstream>
#include <streambuf>
#include <string>
#include <fstream>
#include <fcntl.h>
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#define dup _dup
#define dup2 _dup2
#define fd_close _close
#define unlink _unlink
#define STDERR_FD _fileno(stderr)
#define OPEN_FLAGS (_O_WRONLY | _O_CREAT | _O_TRUNC)
#define OPEN_MODE (_S_IREAD | _S_IWRITE)
#define open _open
#else
#include <unistd.h>
#define fd_close close
#define STDERR_FD STDERR_FILENO
#define OPEN_FLAGS (O_WRONLY | O_CREAT | O_TRUNC)
#define OPEN_MODE 0644
#endif
// Class to capture all stderr output (HIP logging uses stderr)
class OutCapture {
private:
std::stringstream captured_stream_;
std::streambuf* cerr_backup_;
int stderr_backup_;
std::string temp_file_;
static std::string getTempFilePath() {
#ifdef _WIN32
char temp_path[MAX_PATH];
if (GetTempPathA(MAX_PATH, temp_path)) {
return std::string(temp_path) + "hip_stderr_capture.txt";
}
// Fallback to current directory
return "hip_stderr_capture.txt";
#else
return "/tmp/hip_stderr_capture.txt";
#endif
}
public:
OutCapture() : temp_file_(getTempFilePath()) {
// Backup original cerr stream buffer (HIP logging uses stderr)
cerr_backup_ = std::cerr.rdbuf();
// Backup original stderr file descriptor
stderr_backup_ = dup(STDERR_FD);
}
void startCapture() {
// Clear any previous content
captured_stream_.str("");
captured_stream_.clear();
// Redirect std::cerr to our stringstream
std::cerr.rdbuf(captured_stream_.rdbuf());
// Redirect stderr file descriptor to temp file (for fprintf to stderr)
int temp_fd = open(temp_file_.c_str(), OPEN_FLAGS, OPEN_MODE);
if (temp_fd != -1) {
dup2(temp_fd, STDERR_FD);
fd_close(temp_fd);
}
}
std::string stopCapture() {
// Restore original cerr stream
std::cerr.rdbuf(cerr_backup_);
// Restore original stderr file descriptor
dup2(stderr_backup_, STDERR_FD);
// Read from temp file (captures fprintf(stderr) output from HIP logging)
std::ifstream temp_file(temp_file_);
std::string file_content;
if (temp_file.is_open()) {
std::string line;
while (std::getline(temp_file, line)) {
file_content += line + "\n";
}
temp_file.close();
}
// Combine both captures: C++ streams and file descriptor output
std::string stream_content = captured_stream_.str();
std::string total_output = stream_content + file_content;
// Clean up temp file
unlink(temp_file_.c_str());
return total_output;
}
~OutCapture() {
// Ensure everything is restored
std::cerr.rdbuf(cerr_backup_);
dup2(stderr_backup_, STDERR_FD);
fd_close(stderr_backup_);
unlink(temp_file_.c_str());
}
};