kfdtest: add runtime enable and attach test
Add debug attach and runtime enable test for attaching to a spawned and
running process.
Signed-off-by: Jonathan Kim <jonathan.kim@amd.com>
Change-Id: I72302ff73494d9dae0c79a299508085d7ca0552b
[ROCm/ROCR-Runtime commit: 097ee967d1]
This commit is contained in:
committed by
Jonathan Kim
parent
fb140303bb
commit
115ff68bda
@@ -196,6 +196,7 @@ set (SRC_FILES gtest-1.6.0/gtest-all.cpp
|
||||
src/KFDExceptionTest.cpp
|
||||
src/KFDGraphicsInterop.cpp
|
||||
src/KFDPerfCounters.cpp
|
||||
src/KFDDBGTest.cpp
|
||||
src/KFDGWSTest.cpp
|
||||
src/KFDIPCTest.cpp
|
||||
src/KFDASMTest.cpp
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BaseDebug.hpp"
|
||||
#include "KFDDBGTest.hpp"
|
||||
#include <sys/ptrace.h>
|
||||
#include <poll.h>
|
||||
@@ -50,3 +51,189 @@ void KFDDBGTest::TearDown() {
|
||||
ROUTINE_END
|
||||
}
|
||||
|
||||
/*
|
||||
* To test debug attaching to a spawned process (i.e. attach prior to the tracee
|
||||
* opening a KFD device), have the child request the parent to PTRACE attach and
|
||||
* wait for the parent to debug attach then allow the child to runtime enable.
|
||||
*
|
||||
* The following will be exercised:
|
||||
* - The KFD shall create a KFD process on behalf of the tracee during debug
|
||||
* attach since the tracee has not opened a KFD device.
|
||||
* - Runtime enable on the tracee shall raise an event to the debugging parent
|
||||
* and block until parent has signalled that it has recieved the runtime
|
||||
* enable event.
|
||||
* - Tracee should follow a similar hand shake for runtime disable and debug
|
||||
* detach should follow.
|
||||
*
|
||||
* */
|
||||
TEST_F(KFDDBGTest, AttachToSpawnedProcess) {
|
||||
TEST_START(TESTPROFILE_RUNALL)
|
||||
if (m_FamilyId >= FAMILY_AI) {
|
||||
|
||||
if (hsaKmtCheckRuntimeDebugSupport()) {
|
||||
LOG() << "Skip test as debug API not supported";
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pid_t childPid = fork();
|
||||
|
||||
if (childPid == 0) { /* Debugged process */
|
||||
uint32_t rDebug;
|
||||
int r;
|
||||
|
||||
/* Let parent become the debugger and wait for attach. */
|
||||
ptrace(PTRACE_TRACEME);
|
||||
raise(SIGSTOP);
|
||||
|
||||
r = hsaKmtOpenKFD();
|
||||
|
||||
if (r != HSAKMT_STATUS_SUCCESS) {
|
||||
WARN() << "KFD open failed in debugged process" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LOG() << std::dec << "--- Debugged PID " << getpid() << " runtime enable" << std::endl;
|
||||
|
||||
r = hsaKmtRuntimeEnable(&rDebug, true);
|
||||
|
||||
if (r != HSAKMT_STATUS_SUCCESS) {
|
||||
WARN() << "Runtime enabled failed" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LOG() << std::dec << "--- Debugged PID " << getpid() << " runtime disable and exit" << std::endl;
|
||||
|
||||
hsaKmtRuntimeDisable();
|
||||
|
||||
exit(0);
|
||||
} else {
|
||||
BaseDebug *debug = new BaseDebug();
|
||||
struct kfd_runtime_info r_info = {0};
|
||||
uint64_t runtimeMask = KFD_EC_MASK(EC_PROCESS_RUNTIME);
|
||||
int childStatus;
|
||||
|
||||
waitpid(childPid, &childStatus, 0);
|
||||
while (!WIFSTOPPED(childStatus));
|
||||
|
||||
/* Attach and let new debugged process continue with runtime enable */
|
||||
LOG() << std::dec << "Attaching to PID " << childPid << std::endl;
|
||||
ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), childPid, runtimeMask));
|
||||
ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_DISABLED);
|
||||
ASSERT_EQ(r_info.ttmp_setup, false);
|
||||
|
||||
ptrace(PTRACE_CONT, childPid, NULL, NULL);
|
||||
|
||||
/* Wait and unblock runtime enable */
|
||||
ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));
|
||||
ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));
|
||||
ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));
|
||||
|
||||
/* Wait and unblock runtime disable */
|
||||
ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));
|
||||
ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));
|
||||
ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));
|
||||
|
||||
LOG() << std::dec << "Detaching from PID " << childPid << std::endl;
|
||||
debug->Detach();
|
||||
|
||||
ptrace(PTRACE_DETACH, childPid, NULL, NULL);
|
||||
|
||||
LOG() << std::dec << "Waiting on PID " << childPid << " to exit" << std::endl;
|
||||
waitpid(childPid, &childStatus, 0);
|
||||
EXPECT_EQ(WIFEXITED(childStatus), true);
|
||||
EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);
|
||||
}
|
||||
} else {
|
||||
LOG() << "Skipping test: Test not supported on family ID 0x"
|
||||
<< m_FamilyId << "." << std::endl;
|
||||
}
|
||||
exit:
|
||||
LOG() << std::endl;
|
||||
TEST_END
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike AttachToSpawnedProcess, the debug parent will only attach after
|
||||
* a non-blocked runtime enable by the tracee. The parent should expect
|
||||
* a status update that the tracee is runtime enabled on debug attach.
|
||||
* Cleanup with appropriate runtime disable and debug detach handshake.
|
||||
*/
|
||||
TEST_F(KFDDBGTest, AttachToRunningProcess) {
|
||||
TEST_START(TESTPROFILE_RUNALL)
|
||||
if (m_FamilyId >= FAMILY_AI) {
|
||||
|
||||
if (hsaKmtCheckRuntimeDebugSupport()) {
|
||||
LOG() << "Skip test as debug API not supported";
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pid_t childPid = fork();
|
||||
|
||||
if (childPid == 0) { /* Debugged process */
|
||||
uint32_t rDebug;
|
||||
int r;
|
||||
|
||||
r = hsaKmtOpenKFD();
|
||||
|
||||
if (r != HSAKMT_STATUS_SUCCESS) {
|
||||
WARN() << "KFD open failed in debugged process" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LOG() << std::dec << "--- Debugged PID " << getpid() << " runtime enable" << std::endl;
|
||||
|
||||
r = hsaKmtRuntimeEnable(&rDebug, true);
|
||||
if (r != HSAKMT_STATUS_SUCCESS) {
|
||||
WARN() << "Runtime enabled failed" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Let parent become the debugger and wait for attach. */
|
||||
ptrace(PTRACE_TRACEME);
|
||||
raise(SIGSTOP);
|
||||
|
||||
LOG() << std::dec << "--- Debugged PID " << getpid() << " runtime disable and exit" << std::endl;
|
||||
|
||||
hsaKmtRuntimeDisable();
|
||||
|
||||
exit(0);
|
||||
} else {
|
||||
BaseDebug *debug = new BaseDebug();
|
||||
struct kfd_runtime_info r_info = {0};
|
||||
uint64_t runtimeMask = KFD_EC_MASK(EC_PROCESS_RUNTIME);
|
||||
int childStatus;
|
||||
|
||||
waitpid(childPid, &childStatus, 0);
|
||||
while (!WIFSTOPPED(childStatus));
|
||||
|
||||
/* Attach to running process and let it continue */
|
||||
LOG() << std::dec << "Attaching to PID " << childPid << std::endl;
|
||||
ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), childPid, runtimeMask));
|
||||
ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED);
|
||||
ASSERT_EQ(r_info.ttmp_setup, true);
|
||||
|
||||
ptrace(PTRACE_CONT, childPid, NULL, NULL);
|
||||
|
||||
/* Wait and unblock runtime disable */
|
||||
ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));
|
||||
ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));
|
||||
ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));
|
||||
|
||||
LOG() << std::dec << "Detaching from PID " << childPid << std::endl;
|
||||
debug->Detach();
|
||||
|
||||
ptrace(PTRACE_DETACH, childPid, NULL, NULL);
|
||||
|
||||
LOG() << std::dec << "Waiting on PID " << childPid << " to exit" << std::endl;
|
||||
waitpid(childPid, &childStatus, 0);
|
||||
EXPECT_EQ(WIFEXITED(childStatus), true);
|
||||
EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);
|
||||
}
|
||||
} else {
|
||||
LOG() << "Skipping test: Test not supported on family ID 0x"
|
||||
<< m_FamilyId << "." << std::endl;
|
||||
}
|
||||
exit:
|
||||
LOG() << std::endl;
|
||||
TEST_END
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user