xref: /freebsd-src/contrib/llvm-project/openmp/runtime/src/kmp_debugger.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric #include "kmp_config.h"
20b57cec5SDimitry Andric 
30b57cec5SDimitry Andric #if USE_DEBUGGER
40b57cec5SDimitry Andric /*
50b57cec5SDimitry Andric  * kmp_debugger.cpp -- debugger support.
60b57cec5SDimitry Andric  */
70b57cec5SDimitry Andric 
80b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric //
100b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
110b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
120b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "kmp.h"
170b57cec5SDimitry Andric #include "kmp_lock.h"
180b57cec5SDimitry Andric #include "kmp_omp.h"
190b57cec5SDimitry Andric #include "kmp_str.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric // NOTE: All variable names are known to the debugger, do not change!
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #ifdef __cplusplus
240b57cec5SDimitry Andric extern "C" {
250b57cec5SDimitry Andric extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
260b57cec5SDimitry Andric } // extern "C"
270b57cec5SDimitry Andric #endif // __cplusplus
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric int __kmp_debugging = FALSE; // Boolean whether currently debugging OpenMP RTL.
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #define offset_and_size_of(structure, field)                                   \
320b57cec5SDimitry Andric   { offsetof(structure, field), sizeof(((structure *)NULL)->field) }
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric #define offset_and_size_not_available                                          \
350b57cec5SDimitry Andric   { -1, -1 }
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric #define addr_and_size_of(var)                                                  \
380b57cec5SDimitry Andric   { (kmp_uint64)(&var), sizeof(var) }
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric #define nthr_buffer_size 1024
410b57cec5SDimitry Andric static kmp_int32 kmp_omp_nthr_info_buffer[nthr_buffer_size] = {
420b57cec5SDimitry Andric     nthr_buffer_size * sizeof(kmp_int32)};
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric /* TODO: Check punctuation for various platforms here */
450b57cec5SDimitry Andric static char func_microtask[] = "__kmp_invoke_microtask";
460b57cec5SDimitry Andric static char func_fork[] = "__kmpc_fork_call";
470b57cec5SDimitry Andric static char func_fork_teams[] = "__kmpc_fork_teams";
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric // Various info about runtime structures: addresses, field offsets, sizes, etc.
500b57cec5SDimitry Andric kmp_omp_struct_info_t __kmp_omp_debug_struct_info = {
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric     /* Change this only if you make a fundamental data structure change here */
530b57cec5SDimitry Andric     KMP_OMP_VERSION,
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric     /* sanity check.  Only should be checked if versions are identical
560b57cec5SDimitry Andric      * This is also used for backward compatibility to get the runtime
570b57cec5SDimitry Andric      * structure size if it the runtime is older than the interface */
580b57cec5SDimitry Andric     sizeof(kmp_omp_struct_info_t),
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric     /* OpenMP RTL version info. */
610b57cec5SDimitry Andric     addr_and_size_of(__kmp_version_major),
620b57cec5SDimitry Andric     addr_and_size_of(__kmp_version_minor),
630b57cec5SDimitry Andric     addr_and_size_of(__kmp_version_build),
640b57cec5SDimitry Andric     addr_and_size_of(__kmp_openmp_version),
650b57cec5SDimitry Andric     {(kmp_uint64)(__kmp_copyright) + KMP_VERSION_MAGIC_LEN,
660b57cec5SDimitry Andric      0}, // Skip magic prefix.
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric     /* Various globals. */
690b57cec5SDimitry Andric     addr_and_size_of(__kmp_threads),
700b57cec5SDimitry Andric     addr_and_size_of(__kmp_root),
710b57cec5SDimitry Andric     addr_and_size_of(__kmp_threads_capacity),
720b57cec5SDimitry Andric #if KMP_USE_MONITOR
730b57cec5SDimitry Andric     addr_and_size_of(__kmp_monitor),
740b57cec5SDimitry Andric #endif
750b57cec5SDimitry Andric #if !KMP_USE_DYNAMIC_LOCK
760b57cec5SDimitry Andric     addr_and_size_of(__kmp_user_lock_table),
770b57cec5SDimitry Andric #endif
780b57cec5SDimitry Andric     addr_and_size_of(func_microtask),
790b57cec5SDimitry Andric     addr_and_size_of(func_fork),
800b57cec5SDimitry Andric     addr_and_size_of(func_fork_teams),
810b57cec5SDimitry Andric     addr_and_size_of(__kmp_team_counter),
820b57cec5SDimitry Andric     addr_and_size_of(__kmp_task_counter),
830b57cec5SDimitry Andric     addr_and_size_of(kmp_omp_nthr_info_buffer),
840b57cec5SDimitry Andric     sizeof(void *),
850b57cec5SDimitry Andric     OMP_LOCK_T_SIZE < sizeof(void *),
860b57cec5SDimitry Andric     bs_last_barrier,
870b57cec5SDimitry Andric     INITIAL_TASK_DEQUE_SIZE,
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric     // thread structure information
900b57cec5SDimitry Andric     sizeof(kmp_base_info_t),
910b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_info),
920b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_team),
930b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_root),
940b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_serial_team),
950b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_ident),
960b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_spin_here),
970b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_next_waiting),
980b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_task_team),
990b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_current_task),
1000b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_task_state),
1010b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_bar),
1020b57cec5SDimitry Andric     offset_and_size_of(kmp_bstate_t, b_worker_arrived),
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric     // teams information
1050b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_teams_microtask),
1060b57cec5SDimitry Andric     offset_and_size_of(kmp_base_info_t, th_teams_level),
1070b57cec5SDimitry Andric     offset_and_size_of(kmp_teams_size_t, nteams),
1080b57cec5SDimitry Andric     offset_and_size_of(kmp_teams_size_t, nth),
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric     // kmp_desc structure (for info field above)
1110b57cec5SDimitry Andric     sizeof(kmp_desc_base_t),
1120b57cec5SDimitry Andric     offset_and_size_of(kmp_desc_base_t, ds_tid),
1130b57cec5SDimitry Andric     offset_and_size_of(kmp_desc_base_t, ds_gtid),
1140b57cec5SDimitry Andric // On Windows* OS, ds_thread contains a thread /handle/, which is not usable,
1150b57cec5SDimitry Andric // while thread /id/ is in ds_thread_id.
1160b57cec5SDimitry Andric #if KMP_OS_WINDOWS
1170b57cec5SDimitry Andric     offset_and_size_of(kmp_desc_base_t, ds_thread_id),
1180b57cec5SDimitry Andric #else
1190b57cec5SDimitry Andric     offset_and_size_of(kmp_desc_base_t, ds_thread),
1200b57cec5SDimitry Andric #endif
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric     // team structure information
1230b57cec5SDimitry Andric     sizeof(kmp_base_team_t),
1240b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_master_tid),
1250b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_ident),
1260b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_parent),
1270b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_nproc),
1280b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_threads),
1290b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_serialized),
1300b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_id),
1310b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_pkfn),
1320b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_task_team),
1330b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_implicit_task_taskdata),
1340b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_cancel_request),
1350b57cec5SDimitry Andric     offset_and_size_of(kmp_base_team_t, t_bar),
1360b57cec5SDimitry Andric     offset_and_size_of(kmp_balign_team_t, b_master_arrived),
1370b57cec5SDimitry Andric     offset_and_size_of(kmp_balign_team_t, b_team_arrived),
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric     // root structure information
1400b57cec5SDimitry Andric     sizeof(kmp_base_root_t),
1410b57cec5SDimitry Andric     offset_and_size_of(kmp_base_root_t, r_root_team),
1420b57cec5SDimitry Andric     offset_and_size_of(kmp_base_root_t, r_hot_team),
1430b57cec5SDimitry Andric     offset_and_size_of(kmp_base_root_t, r_uber_thread),
1440b57cec5SDimitry Andric     offset_and_size_not_available,
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric     // ident structure information
1470b57cec5SDimitry Andric     sizeof(ident_t),
1480b57cec5SDimitry Andric     offset_and_size_of(ident_t, psource),
1490b57cec5SDimitry Andric     offset_and_size_of(ident_t, flags),
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric     // lock structure information
1520b57cec5SDimitry Andric     sizeof(kmp_base_queuing_lock_t),
1530b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, initialized),
1540b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, location),
1550b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, tail_id),
1560b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, head_id),
1570b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, next_ticket),
1580b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, now_serving),
1590b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, owner_id),
1600b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, depth_locked),
1610b57cec5SDimitry Andric     offset_and_size_of(kmp_base_queuing_lock_t, flags),
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric #if !KMP_USE_DYNAMIC_LOCK
1640b57cec5SDimitry Andric     /* Lock table. */
1650b57cec5SDimitry Andric     sizeof(kmp_lock_table_t),
1660b57cec5SDimitry Andric     offset_and_size_of(kmp_lock_table_t, used),
1670b57cec5SDimitry Andric     offset_and_size_of(kmp_lock_table_t, allocated),
1680b57cec5SDimitry Andric     offset_and_size_of(kmp_lock_table_t, table),
1690b57cec5SDimitry Andric #endif
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric     // Task team structure information.
1720b57cec5SDimitry Andric     sizeof(kmp_base_task_team_t),
1730b57cec5SDimitry Andric     offset_and_size_of(kmp_base_task_team_t, tt_threads_data),
1740b57cec5SDimitry Andric     offset_and_size_of(kmp_base_task_team_t, tt_found_tasks),
1750b57cec5SDimitry Andric     offset_and_size_of(kmp_base_task_team_t, tt_nproc),
1760b57cec5SDimitry Andric     offset_and_size_of(kmp_base_task_team_t, tt_unfinished_threads),
1770b57cec5SDimitry Andric     offset_and_size_of(kmp_base_task_team_t, tt_active),
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric     // task_data_t.
1800b57cec5SDimitry Andric     sizeof(kmp_taskdata_t),
1810b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_task_id),
1820b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_flags),
1830b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_team),
1840b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_parent),
1850b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_level),
1860b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_ident),
1870b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_allocated_child_tasks),
1880b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_incomplete_child_tasks),
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_taskwait_ident),
1910b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_taskwait_counter),
1920b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_taskwait_thread),
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_taskgroup),
1950b57cec5SDimitry Andric     offset_and_size_of(kmp_taskgroup_t, count),
1960b57cec5SDimitry Andric     offset_and_size_of(kmp_taskgroup_t, cancel_request),
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric     offset_and_size_of(kmp_taskdata_t, td_depnode),
1990b57cec5SDimitry Andric     offset_and_size_of(kmp_depnode_list_t, node),
2000b57cec5SDimitry Andric     offset_and_size_of(kmp_depnode_list_t, next),
2010b57cec5SDimitry Andric     offset_and_size_of(kmp_base_depnode_t, successors),
2020b57cec5SDimitry Andric     offset_and_size_of(kmp_base_depnode_t, task),
2030b57cec5SDimitry Andric     offset_and_size_of(kmp_base_depnode_t, npredecessors),
2040b57cec5SDimitry Andric     offset_and_size_of(kmp_base_depnode_t, nrefs),
2050b57cec5SDimitry Andric     offset_and_size_of(kmp_task_t, routine),
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric     // thread_data_t.
2080b57cec5SDimitry Andric     sizeof(kmp_thread_data_t),
2090b57cec5SDimitry Andric     offset_and_size_of(kmp_base_thread_data_t, td_deque),
2100b57cec5SDimitry Andric     offset_and_size_of(kmp_base_thread_data_t, td_deque_size),
2110b57cec5SDimitry Andric     offset_and_size_of(kmp_base_thread_data_t, td_deque_head),
2120b57cec5SDimitry Andric     offset_and_size_of(kmp_base_thread_data_t, td_deque_tail),
2130b57cec5SDimitry Andric     offset_and_size_of(kmp_base_thread_data_t, td_deque_ntasks),
2140b57cec5SDimitry Andric     offset_and_size_of(kmp_base_thread_data_t, td_deque_last_stolen),
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric     // The last field.
2170b57cec5SDimitry Andric     KMP_OMP_VERSION,
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric }; // __kmp_omp_debug_struct_info
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric #undef offset_and_size_of
2220b57cec5SDimitry Andric #undef addr_and_size_of
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric /* Intel compiler on IA-32 architecture issues a warning "conversion
2250b57cec5SDimitry Andric   from "unsigned long long" to "char *" may lose significant bits"
2260b57cec5SDimitry Andric   when 64-bit value is assigned to 32-bit pointer. Use this function
2270b57cec5SDimitry Andric   to suppress the warning. */
__kmp_convert_to_ptr(kmp_uint64 addr)2280b57cec5SDimitry Andric static inline void *__kmp_convert_to_ptr(kmp_uint64 addr) {
229*81ad6265SDimitry Andric #if KMP_COMPILER_ICC || KMP_COMPILER_ICX
2300b57cec5SDimitry Andric #pragma warning(push)
2310b57cec5SDimitry Andric #pragma warning(disable : 810) // conversion from "unsigned long long" to "char
2320b57cec5SDimitry Andric // *" may lose significant bits
2330b57cec5SDimitry Andric #pragma warning(disable : 1195) // conversion from integer to smaller pointer
234*81ad6265SDimitry Andric #endif // KMP_COMPILER_ICC || KMP_COMPILER_ICX
2350b57cec5SDimitry Andric   return (void *)addr;
236*81ad6265SDimitry Andric #if KMP_COMPILER_ICC || KMP_COMPILER_ICX
2370b57cec5SDimitry Andric #pragma warning(pop)
238*81ad6265SDimitry Andric #endif // KMP_COMPILER_ICC || KMP_COMPILER_ICX
2390b57cec5SDimitry Andric } // __kmp_convert_to_ptr
2400b57cec5SDimitry Andric 
kmp_location_match(kmp_str_loc_t * loc,kmp_omp_nthr_item_t * item)2410b57cec5SDimitry Andric static int kmp_location_match(kmp_str_loc_t *loc, kmp_omp_nthr_item_t *item) {
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   int file_match = 0;
2440b57cec5SDimitry Andric   int func_match = 0;
2450b57cec5SDimitry Andric   int line_match = 0;
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   char *file = (char *)__kmp_convert_to_ptr(item->file);
2480b57cec5SDimitry Andric   char *func = (char *)__kmp_convert_to_ptr(item->func);
2490b57cec5SDimitry Andric   file_match = __kmp_str_fname_match(&loc->fname, file);
2500b57cec5SDimitry Andric   func_match =
2510b57cec5SDimitry Andric       item->func == 0 // If item->func is NULL, it allows any func name.
2520b57cec5SDimitry Andric       || strcmp(func, "*") == 0 ||
2530b57cec5SDimitry Andric       (loc->func != NULL && strcmp(loc->func, func) == 0);
2540b57cec5SDimitry Andric   line_match =
2550b57cec5SDimitry Andric       item->begin <= loc->line &&
2560b57cec5SDimitry Andric       (item->end <= 0 ||
2570b57cec5SDimitry Andric        loc->line <= item->end); // if item->end <= 0, it means "end of file".
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   return (file_match && func_match && line_match);
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric } // kmp_location_match
2620b57cec5SDimitry Andric 
__kmp_omp_num_threads(ident_t const * ident)2630b57cec5SDimitry Andric int __kmp_omp_num_threads(ident_t const *ident) {
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   int num_threads = 0;
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   kmp_omp_nthr_info_t *info = (kmp_omp_nthr_info_t *)__kmp_convert_to_ptr(
2680b57cec5SDimitry Andric       __kmp_omp_debug_struct_info.nthr_info.addr);
2690b57cec5SDimitry Andric   if (info->num > 0 && info->array != 0) {
2700b57cec5SDimitry Andric     kmp_omp_nthr_item_t *items =
2710b57cec5SDimitry Andric         (kmp_omp_nthr_item_t *)__kmp_convert_to_ptr(info->array);
272e8d8bef9SDimitry Andric     kmp_str_loc_t loc = __kmp_str_loc_init(ident->psource, true);
2730b57cec5SDimitry Andric     int i;
2740b57cec5SDimitry Andric     for (i = 0; i < info->num; ++i) {
2750b57cec5SDimitry Andric       if (kmp_location_match(&loc, &items[i])) {
2760b57cec5SDimitry Andric         num_threads = items[i].num_threads;
2770b57cec5SDimitry Andric       }
2780b57cec5SDimitry Andric     }
2790b57cec5SDimitry Andric     __kmp_str_loc_free(&loc);
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   return num_threads;
2830b57cec5SDimitry Andric   ;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric } // __kmp_omp_num_threads
2860b57cec5SDimitry Andric #endif /* USE_DEBUGGER */
287