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