1*b5893f02SDimitry Andric #include "kmp_config.h"
2*b5893f02SDimitry Andric
3*b5893f02SDimitry Andric #if USE_DEBUGGER
4*b5893f02SDimitry Andric /*
5*b5893f02SDimitry Andric * kmp_debugger.cpp -- debugger support.
6*b5893f02SDimitry Andric */
7*b5893f02SDimitry Andric
8*b5893f02SDimitry Andric //===----------------------------------------------------------------------===//
9*b5893f02SDimitry Andric //
10*b5893f02SDimitry Andric // The LLVM Compiler Infrastructure
11*b5893f02SDimitry Andric //
12*b5893f02SDimitry Andric // This file is dual licensed under the MIT and the University of Illinois Open
13*b5893f02SDimitry Andric // Source Licenses. See LICENSE.txt for details.
14*b5893f02SDimitry Andric //
15*b5893f02SDimitry Andric //===----------------------------------------------------------------------===//
16*b5893f02SDimitry Andric
17*b5893f02SDimitry Andric #include "kmp.h"
18*b5893f02SDimitry Andric #include "kmp_lock.h"
19*b5893f02SDimitry Andric #include "kmp_omp.h"
20*b5893f02SDimitry Andric #include "kmp_str.h"
21*b5893f02SDimitry Andric
22*b5893f02SDimitry Andric // NOTE: All variable names are known to the debugger, do not change!
23*b5893f02SDimitry Andric
24*b5893f02SDimitry Andric #ifdef __cplusplus
25*b5893f02SDimitry Andric extern "C" {
26*b5893f02SDimitry Andric extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
27*b5893f02SDimitry Andric } // extern "C"
28*b5893f02SDimitry Andric #endif // __cplusplus
29*b5893f02SDimitry Andric
30*b5893f02SDimitry Andric int __kmp_debugging = FALSE; // Boolean whether currently debugging OpenMP RTL.
31*b5893f02SDimitry Andric
32*b5893f02SDimitry Andric #define offset_and_size_of(structure, field) \
33*b5893f02SDimitry Andric { offsetof(structure, field), sizeof(((structure *)NULL)->field) }
34*b5893f02SDimitry Andric
35*b5893f02SDimitry Andric #define offset_and_size_not_available \
36*b5893f02SDimitry Andric { -1, -1 }
37*b5893f02SDimitry Andric
38*b5893f02SDimitry Andric #define addr_and_size_of(var) \
39*b5893f02SDimitry Andric { (kmp_uint64)(&var), sizeof(var) }
40*b5893f02SDimitry Andric
41*b5893f02SDimitry Andric #define nthr_buffer_size 1024
42*b5893f02SDimitry Andric static kmp_int32 kmp_omp_nthr_info_buffer[nthr_buffer_size] = {
43*b5893f02SDimitry Andric nthr_buffer_size * sizeof(kmp_int32)};
44*b5893f02SDimitry Andric
45*b5893f02SDimitry Andric /* TODO: Check punctuation for various platforms here */
46*b5893f02SDimitry Andric static char func_microtask[] = "__kmp_invoke_microtask";
47*b5893f02SDimitry Andric static char func_fork[] = "__kmpc_fork_call";
48*b5893f02SDimitry Andric static char func_fork_teams[] = "__kmpc_fork_teams";
49*b5893f02SDimitry Andric
50*b5893f02SDimitry Andric // Various info about runtime structures: addresses, field offsets, sizes, etc.
51*b5893f02SDimitry Andric kmp_omp_struct_info_t __kmp_omp_debug_struct_info = {
52*b5893f02SDimitry Andric
53*b5893f02SDimitry Andric /* Change this only if you make a fundamental data structure change here */
54*b5893f02SDimitry Andric KMP_OMP_VERSION,
55*b5893f02SDimitry Andric
56*b5893f02SDimitry Andric /* sanity check. Only should be checked if versions are identical
57*b5893f02SDimitry Andric * This is also used for backward compatibility to get the runtime
58*b5893f02SDimitry Andric * structure size if it the runtime is older than the interface */
59*b5893f02SDimitry Andric sizeof(kmp_omp_struct_info_t),
60*b5893f02SDimitry Andric
61*b5893f02SDimitry Andric /* OpenMP RTL version info. */
62*b5893f02SDimitry Andric addr_and_size_of(__kmp_version_major),
63*b5893f02SDimitry Andric addr_and_size_of(__kmp_version_minor),
64*b5893f02SDimitry Andric addr_and_size_of(__kmp_version_build),
65*b5893f02SDimitry Andric addr_and_size_of(__kmp_openmp_version),
66*b5893f02SDimitry Andric {(kmp_uint64)(__kmp_copyright) + KMP_VERSION_MAGIC_LEN,
67*b5893f02SDimitry Andric 0}, // Skip magic prefix.
68*b5893f02SDimitry Andric
69*b5893f02SDimitry Andric /* Various globals. */
70*b5893f02SDimitry Andric addr_and_size_of(__kmp_threads),
71*b5893f02SDimitry Andric addr_and_size_of(__kmp_root),
72*b5893f02SDimitry Andric addr_and_size_of(__kmp_threads_capacity),
73*b5893f02SDimitry Andric #if KMP_USE_MONITOR
74*b5893f02SDimitry Andric addr_and_size_of(__kmp_monitor),
75*b5893f02SDimitry Andric #endif
76*b5893f02SDimitry Andric #if !KMP_USE_DYNAMIC_LOCK
77*b5893f02SDimitry Andric addr_and_size_of(__kmp_user_lock_table),
78*b5893f02SDimitry Andric #endif
79*b5893f02SDimitry Andric addr_and_size_of(func_microtask),
80*b5893f02SDimitry Andric addr_and_size_of(func_fork),
81*b5893f02SDimitry Andric addr_and_size_of(func_fork_teams),
82*b5893f02SDimitry Andric addr_and_size_of(__kmp_team_counter),
83*b5893f02SDimitry Andric addr_and_size_of(__kmp_task_counter),
84*b5893f02SDimitry Andric addr_and_size_of(kmp_omp_nthr_info_buffer),
85*b5893f02SDimitry Andric sizeof(void *),
86*b5893f02SDimitry Andric OMP_LOCK_T_SIZE < sizeof(void *),
87*b5893f02SDimitry Andric bs_last_barrier,
88*b5893f02SDimitry Andric INITIAL_TASK_DEQUE_SIZE,
89*b5893f02SDimitry Andric
90*b5893f02SDimitry Andric // thread structure information
91*b5893f02SDimitry Andric sizeof(kmp_base_info_t),
92*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_info),
93*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_team),
94*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_root),
95*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_serial_team),
96*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_ident),
97*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_spin_here),
98*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_next_waiting),
99*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_task_team),
100*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_current_task),
101*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_task_state),
102*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_bar),
103*b5893f02SDimitry Andric offset_and_size_of(kmp_bstate_t, b_worker_arrived),
104*b5893f02SDimitry Andric
105*b5893f02SDimitry Andric #if OMP_40_ENABLED
106*b5893f02SDimitry Andric // teams information
107*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_teams_microtask),
108*b5893f02SDimitry Andric offset_and_size_of(kmp_base_info_t, th_teams_level),
109*b5893f02SDimitry Andric offset_and_size_of(kmp_teams_size_t, nteams),
110*b5893f02SDimitry Andric offset_and_size_of(kmp_teams_size_t, nth),
111*b5893f02SDimitry Andric #endif
112*b5893f02SDimitry Andric
113*b5893f02SDimitry Andric // kmp_desc structure (for info field above)
114*b5893f02SDimitry Andric sizeof(kmp_desc_base_t),
115*b5893f02SDimitry Andric offset_and_size_of(kmp_desc_base_t, ds_tid),
116*b5893f02SDimitry Andric offset_and_size_of(kmp_desc_base_t, ds_gtid),
117*b5893f02SDimitry Andric // On Windows* OS, ds_thread contains a thread /handle/, which is not usable,
118*b5893f02SDimitry Andric // while thread /id/ is in ds_thread_id.
119*b5893f02SDimitry Andric #if KMP_OS_WINDOWS
120*b5893f02SDimitry Andric offset_and_size_of(kmp_desc_base_t, ds_thread_id),
121*b5893f02SDimitry Andric #else
122*b5893f02SDimitry Andric offset_and_size_of(kmp_desc_base_t, ds_thread),
123*b5893f02SDimitry Andric #endif
124*b5893f02SDimitry Andric
125*b5893f02SDimitry Andric // team structure information
126*b5893f02SDimitry Andric sizeof(kmp_base_team_t),
127*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_master_tid),
128*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_ident),
129*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_parent),
130*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_nproc),
131*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_threads),
132*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_serialized),
133*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_id),
134*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_pkfn),
135*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_task_team),
136*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_implicit_task_taskdata),
137*b5893f02SDimitry Andric #if OMP_40_ENABLED
138*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_cancel_request),
139*b5893f02SDimitry Andric #endif
140*b5893f02SDimitry Andric offset_and_size_of(kmp_base_team_t, t_bar),
141*b5893f02SDimitry Andric offset_and_size_of(kmp_balign_team_t, b_master_arrived),
142*b5893f02SDimitry Andric offset_and_size_of(kmp_balign_team_t, b_team_arrived),
143*b5893f02SDimitry Andric
144*b5893f02SDimitry Andric // root structure information
145*b5893f02SDimitry Andric sizeof(kmp_base_root_t),
146*b5893f02SDimitry Andric offset_and_size_of(kmp_base_root_t, r_root_team),
147*b5893f02SDimitry Andric offset_and_size_of(kmp_base_root_t, r_hot_team),
148*b5893f02SDimitry Andric offset_and_size_of(kmp_base_root_t, r_uber_thread),
149*b5893f02SDimitry Andric offset_and_size_not_available,
150*b5893f02SDimitry Andric
151*b5893f02SDimitry Andric // ident structure information
152*b5893f02SDimitry Andric sizeof(ident_t),
153*b5893f02SDimitry Andric offset_and_size_of(ident_t, psource),
154*b5893f02SDimitry Andric offset_and_size_of(ident_t, flags),
155*b5893f02SDimitry Andric
156*b5893f02SDimitry Andric // lock structure information
157*b5893f02SDimitry Andric sizeof(kmp_base_queuing_lock_t),
158*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, initialized),
159*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, location),
160*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, tail_id),
161*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, head_id),
162*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, next_ticket),
163*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, now_serving),
164*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, owner_id),
165*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, depth_locked),
166*b5893f02SDimitry Andric offset_and_size_of(kmp_base_queuing_lock_t, flags),
167*b5893f02SDimitry Andric
168*b5893f02SDimitry Andric #if !KMP_USE_DYNAMIC_LOCK
169*b5893f02SDimitry Andric /* Lock table. */
170*b5893f02SDimitry Andric sizeof(kmp_lock_table_t),
171*b5893f02SDimitry Andric offset_and_size_of(kmp_lock_table_t, used),
172*b5893f02SDimitry Andric offset_and_size_of(kmp_lock_table_t, allocated),
173*b5893f02SDimitry Andric offset_and_size_of(kmp_lock_table_t, table),
174*b5893f02SDimitry Andric #endif
175*b5893f02SDimitry Andric
176*b5893f02SDimitry Andric // Task team structure information.
177*b5893f02SDimitry Andric sizeof(kmp_base_task_team_t),
178*b5893f02SDimitry Andric offset_and_size_of(kmp_base_task_team_t, tt_threads_data),
179*b5893f02SDimitry Andric offset_and_size_of(kmp_base_task_team_t, tt_found_tasks),
180*b5893f02SDimitry Andric offset_and_size_of(kmp_base_task_team_t, tt_nproc),
181*b5893f02SDimitry Andric offset_and_size_of(kmp_base_task_team_t, tt_unfinished_threads),
182*b5893f02SDimitry Andric offset_and_size_of(kmp_base_task_team_t, tt_active),
183*b5893f02SDimitry Andric
184*b5893f02SDimitry Andric // task_data_t.
185*b5893f02SDimitry Andric sizeof(kmp_taskdata_t),
186*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_task_id),
187*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_flags),
188*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_team),
189*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_parent),
190*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_level),
191*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_ident),
192*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_allocated_child_tasks),
193*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_incomplete_child_tasks),
194*b5893f02SDimitry Andric
195*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_taskwait_ident),
196*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_taskwait_counter),
197*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_taskwait_thread),
198*b5893f02SDimitry Andric
199*b5893f02SDimitry Andric #if OMP_40_ENABLED
200*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_taskgroup),
201*b5893f02SDimitry Andric offset_and_size_of(kmp_taskgroup_t, count),
202*b5893f02SDimitry Andric offset_and_size_of(kmp_taskgroup_t, cancel_request),
203*b5893f02SDimitry Andric
204*b5893f02SDimitry Andric offset_and_size_of(kmp_taskdata_t, td_depnode),
205*b5893f02SDimitry Andric offset_and_size_of(kmp_depnode_list_t, node),
206*b5893f02SDimitry Andric offset_and_size_of(kmp_depnode_list_t, next),
207*b5893f02SDimitry Andric offset_and_size_of(kmp_base_depnode_t, successors),
208*b5893f02SDimitry Andric offset_and_size_of(kmp_base_depnode_t, task),
209*b5893f02SDimitry Andric offset_and_size_of(kmp_base_depnode_t, npredecessors),
210*b5893f02SDimitry Andric offset_and_size_of(kmp_base_depnode_t, nrefs),
211*b5893f02SDimitry Andric #endif
212*b5893f02SDimitry Andric offset_and_size_of(kmp_task_t, routine),
213*b5893f02SDimitry Andric
214*b5893f02SDimitry Andric // thread_data_t.
215*b5893f02SDimitry Andric sizeof(kmp_thread_data_t),
216*b5893f02SDimitry Andric offset_and_size_of(kmp_base_thread_data_t, td_deque),
217*b5893f02SDimitry Andric offset_and_size_of(kmp_base_thread_data_t, td_deque_size),
218*b5893f02SDimitry Andric offset_and_size_of(kmp_base_thread_data_t, td_deque_head),
219*b5893f02SDimitry Andric offset_and_size_of(kmp_base_thread_data_t, td_deque_tail),
220*b5893f02SDimitry Andric offset_and_size_of(kmp_base_thread_data_t, td_deque_ntasks),
221*b5893f02SDimitry Andric offset_and_size_of(kmp_base_thread_data_t, td_deque_last_stolen),
222*b5893f02SDimitry Andric
223*b5893f02SDimitry Andric // The last field.
224*b5893f02SDimitry Andric KMP_OMP_VERSION,
225*b5893f02SDimitry Andric
226*b5893f02SDimitry Andric }; // __kmp_omp_debug_struct_info
227*b5893f02SDimitry Andric
228*b5893f02SDimitry Andric #undef offset_and_size_of
229*b5893f02SDimitry Andric #undef addr_and_size_of
230*b5893f02SDimitry Andric
231*b5893f02SDimitry Andric /* Intel compiler on IA-32 architecture issues a warning "conversion
232*b5893f02SDimitry Andric from "unsigned long long" to "char *" may lose significant bits"
233*b5893f02SDimitry Andric when 64-bit value is assigned to 32-bit pointer. Use this function
234*b5893f02SDimitry Andric to suppress the warning. */
__kmp_convert_to_ptr(kmp_uint64 addr)235*b5893f02SDimitry Andric static inline void *__kmp_convert_to_ptr(kmp_uint64 addr) {
236*b5893f02SDimitry Andric #if KMP_COMPILER_ICC
237*b5893f02SDimitry Andric #pragma warning(push)
238*b5893f02SDimitry Andric #pragma warning(disable : 810) // conversion from "unsigned long long" to "char
239*b5893f02SDimitry Andric // *" may lose significant bits
240*b5893f02SDimitry Andric #pragma warning(disable : 1195) // conversion from integer to smaller pointer
241*b5893f02SDimitry Andric #endif // KMP_COMPILER_ICC
242*b5893f02SDimitry Andric return (void *)addr;
243*b5893f02SDimitry Andric #if KMP_COMPILER_ICC
244*b5893f02SDimitry Andric #pragma warning(pop)
245*b5893f02SDimitry Andric #endif // KMP_COMPILER_ICC
246*b5893f02SDimitry Andric } // __kmp_convert_to_ptr
247*b5893f02SDimitry Andric
kmp_location_match(kmp_str_loc_t * loc,kmp_omp_nthr_item_t * item)248*b5893f02SDimitry Andric static int kmp_location_match(kmp_str_loc_t *loc, kmp_omp_nthr_item_t *item) {
249*b5893f02SDimitry Andric
250*b5893f02SDimitry Andric int file_match = 0;
251*b5893f02SDimitry Andric int func_match = 0;
252*b5893f02SDimitry Andric int line_match = 0;
253*b5893f02SDimitry Andric
254*b5893f02SDimitry Andric char *file = (char *)__kmp_convert_to_ptr(item->file);
255*b5893f02SDimitry Andric char *func = (char *)__kmp_convert_to_ptr(item->func);
256*b5893f02SDimitry Andric file_match = __kmp_str_fname_match(&loc->fname, file);
257*b5893f02SDimitry Andric func_match =
258*b5893f02SDimitry Andric item->func == 0 // If item->func is NULL, it allows any func name.
259*b5893f02SDimitry Andric || strcmp(func, "*") == 0 ||
260*b5893f02SDimitry Andric (loc->func != NULL && strcmp(loc->func, func) == 0);
261*b5893f02SDimitry Andric line_match =
262*b5893f02SDimitry Andric item->begin <= loc->line &&
263*b5893f02SDimitry Andric (item->end <= 0 ||
264*b5893f02SDimitry Andric loc->line <= item->end); // if item->end <= 0, it means "end of file".
265*b5893f02SDimitry Andric
266*b5893f02SDimitry Andric return (file_match && func_match && line_match);
267*b5893f02SDimitry Andric
268*b5893f02SDimitry Andric } // kmp_location_match
269*b5893f02SDimitry Andric
__kmp_omp_num_threads(ident_t const * ident)270*b5893f02SDimitry Andric int __kmp_omp_num_threads(ident_t const *ident) {
271*b5893f02SDimitry Andric
272*b5893f02SDimitry Andric int num_threads = 0;
273*b5893f02SDimitry Andric
274*b5893f02SDimitry Andric kmp_omp_nthr_info_t *info = (kmp_omp_nthr_info_t *)__kmp_convert_to_ptr(
275*b5893f02SDimitry Andric __kmp_omp_debug_struct_info.nthr_info.addr);
276*b5893f02SDimitry Andric if (info->num > 0 && info->array != 0) {
277*b5893f02SDimitry Andric kmp_omp_nthr_item_t *items =
278*b5893f02SDimitry Andric (kmp_omp_nthr_item_t *)__kmp_convert_to_ptr(info->array);
279*b5893f02SDimitry Andric kmp_str_loc_t loc = __kmp_str_loc_init(ident->psource, 1);
280*b5893f02SDimitry Andric int i;
281*b5893f02SDimitry Andric for (i = 0; i < info->num; ++i) {
282*b5893f02SDimitry Andric if (kmp_location_match(&loc, &items[i])) {
283*b5893f02SDimitry Andric num_threads = items[i].num_threads;
284*b5893f02SDimitry Andric }
285*b5893f02SDimitry Andric }
286*b5893f02SDimitry Andric __kmp_str_loc_free(&loc);
287*b5893f02SDimitry Andric }
288*b5893f02SDimitry Andric
289*b5893f02SDimitry Andric return num_threads;
290*b5893f02SDimitry Andric ;
291*b5893f02SDimitry Andric
292*b5893f02SDimitry Andric } // __kmp_omp_num_threads
293*b5893f02SDimitry Andric #endif /* USE_DEBUGGER */
294