spdk_top: allocate a copy of strings during thread display routine

The display_thread() function is the only one that needs to use a copy
of thread data, as threads might be moved between the cores during
SPDK application lifetime.
To avoid problems with using freed memory in the copied thread
structures, make sure the data is always present, by allocating a copy
of necessary strings. This will ensure that even after we have already
freed the globals holding data from RPC, the pointers used to display
the names and cpumasks will still have something to point to.

Fixes #2635

Change-Id: If9228ee199a774d208ddd6ff846532be3ef2012d
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14141
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Dong Yi <dongx.yi@intel.com>
This commit is contained in:
Krzysztof Karas 2022-08-22 10:16:50 +00:00 committed by Tomasz Zawadzki
parent 03d4502003
commit 9494e8f54c

View File

@ -2328,6 +2328,14 @@ get_single_thread_info(uint64_t thread_id, struct rpc_thread_info *thread_info)
for (i = 0; i < g_last_threads_count; i++) { for (i = 0; i < g_last_threads_count; i++) {
if (g_threads_info[i].id == thread_id) { if (g_threads_info[i].id == thread_id) {
memcpy(thread_info, &g_threads_info[i], sizeof(struct rpc_thread_info)); memcpy(thread_info, &g_threads_info[i], sizeof(struct rpc_thread_info));
thread_info->name = strdup(g_threads_info[i].name);
thread_info->cpumask = strdup(g_threads_info[i].cpumask);
if (thread_info->name == NULL || thread_info->cpumask == NULL) {
print_bottom_message("Unable to allocate memory for thread name and cpumask. Exiting pop-up.");
return -1;
}
return 0; return 0;
} }
} }
@ -2420,6 +2428,10 @@ display_thread(uint64_t thread_id, uint8_t current_page, uint8_t active_tab,
pthread_mutex_lock(&g_thread_lock); pthread_mutex_lock(&g_thread_lock);
if (get_single_thread_info(thread_id, &thread_info)) { if (get_single_thread_info(thread_id, &thread_info)) {
pthread_mutex_unlock(&g_thread_lock); pthread_mutex_unlock(&g_thread_lock);
free(thread_info.name);
free(thread_info.cpumask);
thread_info.name = NULL;
thread_info.cpumask = NULL;
return; return;
} }
pollers_count = thread_info.active_pollers_count + pollers_count = thread_info.active_pollers_count +
@ -2489,6 +2501,10 @@ display_thread(uint64_t thread_id, uint8_t current_page, uint8_t active_tab,
} }
last_pollers_count = pollers_count; last_pollers_count = pollers_count;
free(thread_info.name);
free(thread_info.cpumask);
thread_info.name = NULL;
thread_info.cpumask = NULL;
} }
del_panel(thread_panel); del_panel(thread_panel);