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