/* Target-dependent code for ROCm.
- Copyright (C) 2019 Free Software Foundation, Inc.
- Copyright (C) 2019 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved.
This file is part of GDB.
struct rocm_inferior_info
{
/* The amd_dbgapi_process_id for this inferior. */
- amd_dbgapi_process_id_t process_id;
+ amd_dbgapi_process_id_t process_id{ AMD_DBGAPI_PROCESS_NONE };
/* The amd_dbgapi_notifier_t for this inferior. */
- amd_dbgapi_notifier_t notifier;
+ amd_dbgapi_notifier_t notifier{ -1 };
/* True if commit_resume should all-start the GPU queues. */
bool commit_resume_all_start;
+ /* True is the inferior has exited. */
+ bool has_exited{ false };
+
std::unordered_map<decltype (amd_dbgapi_breakpoint_id_t::handle),
struct breakpoint *>
breakpoint_map;
return arch_stratum;
}
+ void close () override;
void mourn_inferior () override;
void async (int enable) override;
/* Flush the event pipe. */
-void
+static void
async_file_flush (void)
{
int ret;
return get_rocm_inferior_info (inferior)->process_id;
}
+static void
+rocm_breakpoint_re_set (struct breakpoint *b)
+{
+}
+
static void
rocm_breakpoint_check_status (struct bpstats *bs)
{
if (!ptid_is_gpu (tp->ptid))
return beneath ()->thread_name (tp);
- amd_dbgapi_process_id_t process_id = get_amd_dbgapi_process_id (tp->inf);
- amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (tp->ptid);
- amd_dbgapi_dispatch_id_t dispatch_id;
- amd_dbgapi_global_address_t kernel_addr;
+ /* Return the process's comm value—that is, the command name associated with
+ the process. */
- if (amd_dbgapi_wave_get_info (process_id, wave_id,
- AMD_DBGAPI_WAVE_INFO_DISPATCH,
- sizeof (dispatch_id), &dispatch_id)
- != AMD_DBGAPI_STATUS_SUCCESS
- || amd_dbgapi_dispatch_get_info (
- process_id, dispatch_id,
- AMD_DBGAPI_DISPATCH_INFO_KERNEL_ENTRY_ADDRESS,
- sizeof (kernel_addr), &kernel_addr)
- != AMD_DBGAPI_STATUS_SUCCESS)
- return NULL;
+ char comm_path[128];
+ xsnprintf (comm_path, sizeof (comm_path), "/proc/%ld/comm",
+ (long)tp->ptid.pid ());
- struct bound_minimal_symbol msymbol
- = lookup_minimal_symbol_by_pc_section (kernel_addr, nullptr);
+ gdb_file_up comm_file = gdb_fopen_cloexec (comm_path, "r");
+ if (!comm_file)
+ return nullptr;
- if (msymbol.minsym != NULL)
- {
- static char buf[256];
- char *endp;
+#if !defined(TASK_COMM_LEN)
+#define TASK_COMM_LEN 16 /* As defined in the kernel's sched.h. */
+#endif
- xsnprintf (buf, sizeof (buf), "%s", msymbol.minsym->print_name ());
+ static char comm_buf[TASK_COMM_LEN];
+ const char *comm_value;
- /* Strip the arguments from the demangled function name. */
- if ((endp = strchr (buf, '(')))
- *endp = '\0';
+ comm_value = fgets (comm_buf, sizeof (comm_buf), comm_file.get ());
+ comm_buf[sizeof (comm_buf) - 1] = '\0';
- return buf;
+ /* Make sure there is no newline at the end. */
+ if (comm_value)
+ {
+ for (int i = 0; i < sizeof (comm_buf); i++)
+ if (comm_buf[i] == '\n')
+ {
+ comm_buf[i] = '\0';
+ break;
+ }
}
- return NULL;
+ return comm_value;
}
std::string
AMD_DBGAPI_WAVE_INFO_WAVE_NUMBER_IN_WORK_GROUP,
sizeof (wave_in_group), &wave_in_group)
!= AMD_DBGAPI_STATUS_SUCCESS)
- return std::string ("ROCm Thread");
+ return std::string ("AMDGPU Thread");
else
- return string_printf ("ROCm Thread %ld.%ld (%d,%d,%d)/%d",
+ return string_printf ("AMDGPU Thread %ld.%ld (%d,%d,%d)/%d",
dispatch_id.handle, wave_id.handle, group_ids[2],
group_ids[1], group_ids[0], wave_in_group);
}
AMD_DBGAPI_ARCHITECTURE_INFO_DEFAULT_GLOBAL_ADDRESS_SPACE,
sizeof (address_space_id), &address_space_id)
!= AMD_DBGAPI_STATUS_SUCCESS)
- error (_ ("Couldn't get default global address space"));
+ return TARGET_XFER_EOF;
size_t len = requested_len;
amd_dbgapi_status_t status;
process_id, wave_id, 0, address_space_id, offset, &len, writebuf);
if (status != AMD_DBGAPI_STATUS_SUCCESS)
- {
- if (status != AMD_DBGAPI_STATUS_ERROR_MEMORY_ACCESS)
- error (_ ("amd_dbgapi_%s_memory failed (rc=%d"),
- readbuf ? "read" : "write", status);
- return TARGET_XFER_EOF;
- }
+ return TARGET_XFER_EOF;
*xfered_len = len;
return TARGET_XFER_OK;
}
else
{
- delete_file_handler (rocm_event_pipe[0]);
-
if (rocm_event_pipe[0] == -1)
return;
+ delete_file_handler (rocm_event_pipe[0]);
+
::close (rocm_event_pipe[0]);
::close (rocm_event_pipe[1]);
rocm_event_pipe[0] = -1;
return software_breakpoint_inserted_here_p (regcache->aspace (), bkpt_pc);
}
+void
+rocm_target_ops::close ()
+{
+ /* Unregister from the event loop. */
+ async (0);
+ beneath ()->close ();
+}
+
void
rocm_target_ops::mourn_inferior ()
{
{
for (inferior *inf : all_inferiors ())
{
- amd_dbgapi_process_id_t process_id = get_amd_dbgapi_process_id (inf);
+ amd_dbgapi_process_id_t process_id;
amd_dbgapi_wave_id_t *wave_list;
size_t count;
+ process_id = get_amd_dbgapi_process_id (inf);
+ if (process_id.handle == AMD_DBGAPI_PROCESS_NONE.handle)
+ {
+ /* The inferior may not be attached yet. */
+ continue;
+ }
+
amd_dbgapi_changed_t changed;
amd_dbgapi_status_t status;
if ((status
= amd_dbgapi_wave_list (process_id, &count, &wave_list, &changed))
!= AMD_DBGAPI_STATUS_SUCCESS)
- error (_ ("amd_dbgapi_wave_list failed (rc=%d"), status);
+ error (_ ("amd_dbgapi_wave_list failed (rc=%d)"), status);
if (changed == AMD_DBGAPI_CHANGED_NO)
continue;
for (auto &&tid : threads)
{
ptid_t wave_ptid (inf->pid, 1, tid);
+ /* FIXME: is this really needed?
amd_dbgapi_wave_state_t state;
if (amd_dbgapi_wave_get_info (
process_id, get_amd_dbgapi_wave_id (wave_ptid),
AMD_DBGAPI_WAVE_INFO_STATE, sizeof (state), &state)
!= AMD_DBGAPI_STATUS_SUCCESS)
- continue;
+ continue;*/
add_thread_silent (wave_ptid);
set_running (wave_ptid, 1);
rocm_target_inferior_exit (struct inferior *inf)
{
auto *info = get_rocm_inferior_info (inf);
+ info->has_exited = true;
amd_dbgapi_deactivated.notify ();
- delete_file_handler (info->notifier);
+ if (info->notifier != -1)
+ delete_file_handler (info->notifier);
amd_dbgapi_process_detach (info->process_id);
static amd_dbgapi_callbacks_t dbgapi_callbacks = {
/* allocate_memory. */
- .allocate_memory = xmalloc,
+ .allocate_memory = malloc,
/* deallocate_memory. */
- .deallocate_memory = xfree,
+ .deallocate_memory = free,
/* get_os_pid. */
.get_os_pid = [] (amd_dbgapi_client_process_id_t client_process_id,
pid_t *pid) -> amd_dbgapi_status_t {
inferior *inf = static_cast<inferior *> (client_process_id);
+ struct rocm_inferior_info *info = get_rocm_inferior_info (inf);
+
+ if (info->has_exited)
+ return AMD_DBGAPI_STATUS_ERROR_PROCESS_EXITED;
*pid = inf->pid;
return AMD_DBGAPI_STATUS_SUCCESS;
{
rocm_breakpoint_ops = bkpt_breakpoint_ops;
rocm_breakpoint_ops.check_status = rocm_breakpoint_check_status;
+ rocm_breakpoint_ops.re_set = rocm_breakpoint_re_set;
}
auto it = info->breakpoint_map.find (breakpoint_id.handle);
void
_initialize_rocm_tdep (void)
{
+ /* Make sure the loaded debugger library version is greater than or equal to
+ the one used to build ROCgdb. */
+ uint32_t major, minor, patch;
+ amd_dbgapi_get_version (&major, &minor, &patch);
+ if (major != AMD_DBGAPI_VERSION_MAJOR || minor < AMD_DBGAPI_VERSION_MINOR)
+ error (
+ _ ("amd-dbgapi library version mismatch, got %d.%d.%d, need %d.%d+"),
+ major, minor, patch, AMD_DBGAPI_VERSION_MAJOR,
+ AMD_DBGAPI_VERSION_MINOR);
+
/* Initialize the ROCm Debug API. */
- if (amd_dbgapi_initialize (&dbgapi_callbacks) != AMD_DBGAPI_STATUS_SUCCESS)
- return;
+ amd_dbgapi_status_t status = amd_dbgapi_initialize (&dbgapi_callbacks);
+ if (status != AMD_DBGAPI_STATUS_SUCCESS)
+ error (_ ("amd-dbgapi failed to initialize (rc=%d)"), status);
/* Set the initial log level. */
amd_dbgapi_set_log_level (get_debug_amd_dbgapi_log_level ());