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