diff options
Diffstat (limited to 'openmp/libompd/gdb-plugin')
-rw-r--r-- | openmp/libompd/gdb-plugin/ompd/__init__.py | 21 | ||||
-rw-r--r-- | openmp/libompd/gdb-plugin/ompd/frame_filter.py | 541 | ||||
-rw-r--r-- | openmp/libompd/gdb-plugin/ompd/ompd.py | 1152 | ||||
-rw-r--r-- | openmp/libompd/gdb-plugin/ompd/ompd_address_space.py | 759 | ||||
-rw-r--r-- | openmp/libompd/gdb-plugin/ompd/ompd_callbacks.py | 138 | ||||
-rw-r--r-- | openmp/libompd/gdb-plugin/ompd/ompd_handles.py | 360 |
6 files changed, 1668 insertions, 1303 deletions
diff --git a/openmp/libompd/gdb-plugin/ompd/__init__.py b/openmp/libompd/gdb-plugin/ompd/__init__.py index c2a12f5..b9f572d 100644 --- a/openmp/libompd/gdb-plugin/ompd/__init__.py +++ b/openmp/libompd/gdb-plugin/ompd/__init__.py @@ -3,13 +3,14 @@ import os.path import traceback if __name__ == "__main__": - try: - sys.path.append(os.path.dirname(__file__)) - - import ompd - ompd.main() - print('OMPD GDB support loaded') - print('Run \'ompd init\' to start debugging') - except Exception as e: - traceback.print_exc() - print('Error: OMPD support could not be loaded', e) + try: + sys.path.append(os.path.dirname(__file__)) + + import ompd + + ompd.main() + print("OMPD GDB support loaded") + print("Run 'ompd init' to start debugging") + except Exception as e: + traceback.print_exc() + print("Error: OMPD support could not be loaded", e) diff --git a/openmp/libompd/gdb-plugin/ompd/frame_filter.py b/openmp/libompd/gdb-plugin/ompd/frame_filter.py index 9f6b914..0b049bd 100644 --- a/openmp/libompd/gdb-plugin/ompd/frame_filter.py +++ b/openmp/libompd/gdb-plugin/ompd/frame_filter.py @@ -9,248 +9,303 @@ from tempfile import NamedTemporaryFile class OmpdFrameDecorator(FrameDecorator): - - def __init__(self, fobj, curr_task_handle): - """Initializes a FrameDecorator with the given GDB Frame object. The global OMPD address space defined in - ompd.py is set as well. - """ - super(OmpdFrameDecorator, self).__init__(fobj) - self.addr_space = ompd.addr_space - self.fobj = None - if isinstance(fobj, gdb.Frame): - self.fobj = fobj - elif isinstance(fobj, FrameDecorator): - self.fobj = fobj.inferior_frame() - self.curr_task_handle = curr_task_handle - - def function(self): - """This appends the name of a frame that is printed with the information whether the task started in the frame - is implicit or explicit. The ICVs are evaluated to determine that. - """ - name = str(self.fobj.name()) - - if self.curr_task_handle is None: - return name - - icv_value = ompdModule.call_ompd_get_icv_from_scope(self.curr_task_handle, ompd.icv_map['implicit-task-var'][1], ompd.icv_map['implicit-task-var'][0]) - if icv_value == 0: - name = '@thread %i: %s "#pragma omp task"' % (gdb.selected_thread().num, name) - elif icv_value == 1: - name = '@thread %i: %s "#pragma omp parallel"' % (gdb.selected_thread().num, name) - else: - name = '@thread %i: %s' % (gdb.selected_thread().num, name) - return name + def __init__(self, fobj, curr_task_handle): + """Initializes a FrameDecorator with the given GDB Frame object. The global OMPD address space defined in + ompd.py is set as well. + """ + super(OmpdFrameDecorator, self).__init__(fobj) + self.addr_space = ompd.addr_space + self.fobj = None + if isinstance(fobj, gdb.Frame): + self.fobj = fobj + elif isinstance(fobj, FrameDecorator): + self.fobj = fobj.inferior_frame() + self.curr_task_handle = curr_task_handle + + def function(self): + """This appends the name of a frame that is printed with the information whether the task started in the frame + is implicit or explicit. The ICVs are evaluated to determine that. + """ + name = str(self.fobj.name()) + + if self.curr_task_handle is None: + return name + + icv_value = ompdModule.call_ompd_get_icv_from_scope( + self.curr_task_handle, + ompd.icv_map["implicit-task-var"][1], + ompd.icv_map["implicit-task-var"][0], + ) + if icv_value == 0: + name = '@thread %i: %s "#pragma omp task"' % ( + gdb.selected_thread().num, + name, + ) + elif icv_value == 1: + name = '@thread %i: %s "#pragma omp parallel"' % ( + gdb.selected_thread().num, + name, + ) + else: + name = "@thread %i: %s" % (gdb.selected_thread().num, name) + return name + class OmpdFrameDecoratorThread(FrameDecorator): - - def __init__(self, fobj): - """Initializes a FrameDecorator with the given GDB Frame object.""" - super(OmpdFrameDecoratorThread, self).__init__(fobj) - if isinstance(fobj, gdb.Frame): - self.fobj = fobj - elif isinstance(fobj, FrameDecorator): - self.fobj = fobj.inferior_frame() - - def function(self): - name = str(self.fobj.name()) - return '@thread %i: %s' % (gdb.selected_thread().num, name) - -class FrameFilter(): - - def __init__(self, addr_space): - """Initializes the FrameFilter, registers is in the GDB runtime and saves the given OMPD address space capsule. - """ - self.addr_space = addr_space - self.name = "Filter" - self.priority = 100 - self.enabled = True - gdb.frame_filters[self.name] = self - self.switched_on = False - self.continue_to_master = False - - def set_switch(self, on_off): - """Prints output when executing 'ompd bt on' or 'ompd bt off'. - """ - self.switched_on = on_off - if self.switched_on: - print('Enabled filter for "bt" output successfully.') - else: - print('Disabled filter for "bt" output successfully.') - - def set_switch_continue(self, on_off): - """Prints output when executing 'ompd bt on continued'." - """ - self.continue_to_master = on_off - if self.continue_to_master: - print('Enabled "bt" mode that continues backtrace on to master thread for worker threads.') - else: - print('Disabled "bt" mode that continues onto master thread.') - - def get_master_frames_for_worker(self, past_thread_num, latest_sp): - """Prints master frames for worker thread with id past_thread_num. - """ - gdb.execute('t 1') - gdb.execute('ompd bt on') - gdb.execute('bt') - - frame = gdb.newest_frame() - - while frame.older() is not None: - print('master frame sp:', str(frame.read_register('sp'))) - yield OmpdFrameDecorator(frame) - frame = frame.older() - print('latest sp:', str(latest_sp)) - - gdb.execute('ompd bt on continued') - gdb.execute('t %d' % int(past_thread_num)) - - - def filter_frames(self, frame_iter): - """Iterates through frames and only returns those that are relevant to the application - being debugged. The OmpdFrameDecorator is applied automatically. - """ - curr_thread_num = gdb.selected_thread().num - is_no_omp_thread = False - if curr_thread_num in self.addr_space.threads: - curr_thread_obj = self.addr_space.threads[curr_thread_num] - self.curr_task = curr_thread_obj.get_current_task() - self.frames = self.curr_task.get_task_frame() - else: - is_no_omp_thread = True - print('Thread %d is no OpenMP thread, printing all frames:' % curr_thread_num) - - stop_iter = False - for x in frame_iter: - if is_no_omp_thread: - yield OmpdFrameDecoratorThread(x) - continue - - if x.inferior_frame().older() is None: - continue - if self.curr_task.task_handle is None: - continue - - gdb_sp = int(str(x.inferior_frame().read_register('sp')), 16) - gdb_sp_next_new = int(str(x.inferior_frame()).split(",")[0].split("=")[1], 16) - if x.inferior_frame().older(): - gdb_sp_next = int(str(x.inferior_frame().older().read_register('sp')), 16) - else: - gdb_sp_next = int(str(x.inferior_frame().read_register('sp')), 16) - while(1): - (ompd_enter_frame, ompd_exit_frame) = self.frames - - if (ompd_enter_frame != 0 and gdb_sp_next_new < ompd_enter_frame): - break - if (ompd_exit_frame != 0 and gdb_sp_next_new < ompd_exit_frame): - if x.inferior_frame().older().older() and int(str(x.inferior_frame().older().older().read_register('sp')), 16) < ompd_exit_frame: - if self.continue_to_master: - yield OmpdFrameDecoratorThread(x) - else: - yield OmpdFrameDecorator(x, self.curr_task.task_handle) - else: - yield OmpdFrameDecorator(x, self.curr_task.task_handle) - break - sched_task_handle = self.curr_task.get_scheduling_task_handle() - - if(sched_task_handle is None): - stop_iter = True - break - - self.curr_task = self.curr_task.get_scheduling_task() - self.frames = self.curr_task.get_task_frame() - if stop_iter: - break - - # implementation of "ompd bt continued" - if self.continue_to_master: - - orig_thread = gdb.selected_thread().num - gdb_threads = dict([(t.num, t) for t in gdb.selected_inferior().threads()]) - - # iterate through generating tasks until outermost task is reached - while(1): - # get OMPD thread id for master thread (systag in GDB output) - try: - master_num = self.curr_task.get_task_parallel().get_thread_in_parallel(0).get_thread_id() - except: - break - # search for thread id without the "l" for long via "thread find" and get GDB thread num from output - hex_str = str(hex(master_num)) - thread_output = gdb.execute('thread find %s' % hex_str[0:len(hex_str)-1], to_string=True).split(" ") - if thread_output[0] == "No": - raise ValueError('Master thread num could not be found!') - gdb_master_num = int(thread_output[1]) - # get task that generated last task of worker thread - try: - self.curr_task = self.curr_task.get_task_parallel().get_task_in_parallel(0).get_generating_task() - except: - break; - self.frames = self.curr_task.get_task_frame() - (enter_frame, exit_frame) = self.frames - if exit_frame == 0: - print('outermost generating task was reached') - break - - # save GDB num for worker thread to change back to it later - worker_thread = gdb.selected_thread().num - - # use InferiorThread.switch() - gdb_threads = dict([(t.num, t) for t in gdb.selected_inferior().threads()]) - gdb_threads[gdb_master_num].switch() - print('#### switching to thread %i ####' % gdb_master_num) - - frame = gdb.newest_frame() - stop_iter = False - - while(not stop_iter): - if self.curr_task.task_handle is None: - break - self.frames = self.curr_task.get_task_frame() - - while frame: - if self.curr_task.task_handle is None: - break - - gdb_sp_next_new = int(str(frame).split(",")[0].split("=")[1], 16) - - if frame.older(): - gdb_sp_next = int(str(frame.older().read_register('sp')), 16) - else: - gdb_sp_next = int(str(frame.read_register('sp')), 16) - - while(1): - (ompd_enter_frame, ompd_exit_frame) = self.frames - - if (ompd_enter_frame != 0 and gdb_sp_next_new < ompd_enter_frame): - break - if (ompd_exit_frame == 0 or gdb_sp_next_new < ompd_exit_frame): - if ompd_exit_frame == 0 or frame.older() and frame.older().older() and int(str(frame.older().older().read_register('sp')), 16) < ompd_exit_frame: - yield OmpdFrameDecoratorThread(frame) - else: - yield OmpdFrameDecorator(frame, self.curr_task.task_handle) - break - sched_task_handle = ompdModule.call_ompd_get_scheduling_task_handle(self.curr_task.task_handle) - - if(sched_task_handle is None): - stop_iter = True - break - self.curr_task = self.curr_task.get_generating_task() - self.frames = self.curr_task.get_task_frame() - - frame = frame.older() - break - - gdb_threads[worker_thread].switch() - - gdb_threads[orig_thread].switch() - - - def filter(self, frame_iter): - """Function is called automatically with every 'bt' executed. If switched on, this will only let revelant frames be printed - or all frames otherwise. If switched on, a FrameDecorator will be applied to state whether '.ompd_task_entry.' refers to an - explicit or implicit task. - """ - if self.switched_on: - return self.filter_frames(frame_iter) - else: - return frame_iter + def __init__(self, fobj): + """Initializes a FrameDecorator with the given GDB Frame object.""" + super(OmpdFrameDecoratorThread, self).__init__(fobj) + if isinstance(fobj, gdb.Frame): + self.fobj = fobj + elif isinstance(fobj, FrameDecorator): + self.fobj = fobj.inferior_frame() + + def function(self): + name = str(self.fobj.name()) + return "@thread %i: %s" % (gdb.selected_thread().num, name) + + +class FrameFilter: + def __init__(self, addr_space): + """Initializes the FrameFilter, registers is in the GDB runtime and saves the given OMPD address space capsule.""" + self.addr_space = addr_space + self.name = "Filter" + self.priority = 100 + self.enabled = True + gdb.frame_filters[self.name] = self + self.switched_on = False + self.continue_to_master = False + + def set_switch(self, on_off): + """Prints output when executing 'ompd bt on' or 'ompd bt off'.""" + self.switched_on = on_off + if self.switched_on: + print('Enabled filter for "bt" output successfully.') + else: + print('Disabled filter for "bt" output successfully.') + + def set_switch_continue(self, on_off): + """Prints output when executing 'ompd bt on continued'." """ + self.continue_to_master = on_off + if self.continue_to_master: + print( + 'Enabled "bt" mode that continues backtrace on to master thread for worker threads.' + ) + else: + print('Disabled "bt" mode that continues onto master thread.') + + def get_master_frames_for_worker(self, past_thread_num, latest_sp): + """Prints master frames for worker thread with id past_thread_num.""" + gdb.execute("t 1") + gdb.execute("ompd bt on") + gdb.execute("bt") + + frame = gdb.newest_frame() + + while frame.older() is not None: + print("master frame sp:", str(frame.read_register("sp"))) + yield OmpdFrameDecorator(frame) + frame = frame.older() + print("latest sp:", str(latest_sp)) + + gdb.execute("ompd bt on continued") + gdb.execute("t %d" % int(past_thread_num)) + + def filter_frames(self, frame_iter): + """Iterates through frames and only returns those that are relevant to the application + being debugged. The OmpdFrameDecorator is applied automatically. + """ + curr_thread_num = gdb.selected_thread().num + is_no_omp_thread = False + if curr_thread_num in self.addr_space.threads: + curr_thread_obj = self.addr_space.threads[curr_thread_num] + self.curr_task = curr_thread_obj.get_current_task() + self.frames = self.curr_task.get_task_frame() + else: + is_no_omp_thread = True + print( + "Thread %d is no OpenMP thread, printing all frames:" % curr_thread_num + ) + + stop_iter = False + for x in frame_iter: + if is_no_omp_thread: + yield OmpdFrameDecoratorThread(x) + continue + + if x.inferior_frame().older() is None: + continue + if self.curr_task.task_handle is None: + continue + + gdb_sp = int(str(x.inferior_frame().read_register("sp")), 16) + gdb_sp_next_new = int( + str(x.inferior_frame()).split(",")[0].split("=")[1], 16 + ) + if x.inferior_frame().older(): + gdb_sp_next = int( + str(x.inferior_frame().older().read_register("sp")), 16 + ) + else: + gdb_sp_next = int(str(x.inferior_frame().read_register("sp")), 16) + while 1: + (ompd_enter_frame, ompd_exit_frame) = self.frames + + if ompd_enter_frame != 0 and gdb_sp_next_new < ompd_enter_frame: + break + if ompd_exit_frame != 0 and gdb_sp_next_new < ompd_exit_frame: + if ( + x.inferior_frame().older().older() + and int( + str(x.inferior_frame().older().older().read_register("sp")), + 16, + ) + < ompd_exit_frame + ): + if self.continue_to_master: + yield OmpdFrameDecoratorThread(x) + else: + yield OmpdFrameDecorator(x, self.curr_task.task_handle) + else: + yield OmpdFrameDecorator(x, self.curr_task.task_handle) + break + sched_task_handle = self.curr_task.get_scheduling_task_handle() + + if sched_task_handle is None: + stop_iter = True + break + + self.curr_task = self.curr_task.get_scheduling_task() + self.frames = self.curr_task.get_task_frame() + if stop_iter: + break + + # implementation of "ompd bt continued" + if self.continue_to_master: + + orig_thread = gdb.selected_thread().num + gdb_threads = dict([(t.num, t) for t in gdb.selected_inferior().threads()]) + + # iterate through generating tasks until outermost task is reached + while 1: + # get OMPD thread id for master thread (systag in GDB output) + try: + master_num = ( + self.curr_task.get_task_parallel() + .get_thread_in_parallel(0) + .get_thread_id() + ) + except: + break + # search for thread id without the "l" for long via "thread find" and get GDB thread num from output + hex_str = str(hex(master_num)) + thread_output = gdb.execute( + "thread find %s" % hex_str[0 : len(hex_str) - 1], to_string=True + ).split(" ") + if thread_output[0] == "No": + raise ValueError("Master thread num could not be found!") + gdb_master_num = int(thread_output[1]) + # get task that generated last task of worker thread + try: + self.curr_task = ( + self.curr_task.get_task_parallel() + .get_task_in_parallel(0) + .get_generating_task() + ) + except: + break + self.frames = self.curr_task.get_task_frame() + (enter_frame, exit_frame) = self.frames + if exit_frame == 0: + print("outermost generating task was reached") + break + + # save GDB num for worker thread to change back to it later + worker_thread = gdb.selected_thread().num + + # use InferiorThread.switch() + gdb_threads = dict( + [(t.num, t) for t in gdb.selected_inferior().threads()] + ) + gdb_threads[gdb_master_num].switch() + print("#### switching to thread %i ####" % gdb_master_num) + + frame = gdb.newest_frame() + stop_iter = False + + while not stop_iter: + if self.curr_task.task_handle is None: + break + self.frames = self.curr_task.get_task_frame() + + while frame: + if self.curr_task.task_handle is None: + break + + gdb_sp_next_new = int( + str(frame).split(",")[0].split("=")[1], 16 + ) + + if frame.older(): + gdb_sp_next = int( + str(frame.older().read_register("sp")), 16 + ) + else: + gdb_sp_next = int(str(frame.read_register("sp")), 16) + + while 1: + (ompd_enter_frame, ompd_exit_frame) = self.frames + + if ( + ompd_enter_frame != 0 + and gdb_sp_next_new < ompd_enter_frame + ): + break + if ( + ompd_exit_frame == 0 + or gdb_sp_next_new < ompd_exit_frame + ): + if ( + ompd_exit_frame == 0 + or frame.older() + and frame.older().older() + and int( + str(frame.older().older().read_register("sp")), + 16, + ) + < ompd_exit_frame + ): + yield OmpdFrameDecoratorThread(frame) + else: + yield OmpdFrameDecorator( + frame, self.curr_task.task_handle + ) + break + sched_task_handle = ( + ompdModule.call_ompd_get_scheduling_task_handle( + self.curr_task.task_handle + ) + ) + + if sched_task_handle is None: + stop_iter = True + break + self.curr_task = self.curr_task.get_generating_task() + self.frames = self.curr_task.get_task_frame() + + frame = frame.older() + break + + gdb_threads[worker_thread].switch() + + gdb_threads[orig_thread].switch() + + def filter(self, frame_iter): + """Function is called automatically with every 'bt' executed. If switched on, this will only let revelant frames be printed + or all frames otherwise. If switched on, a FrameDecorator will be applied to state whether '.ompd_task_entry.' refers to an + explicit or implicit task. + """ + if self.switched_on: + return self.filter_frames(frame_iter) + else: + return frame_iter diff --git a/openmp/libompd/gdb-plugin/ompd/ompd.py b/openmp/libompd/gdb-plugin/ompd/ompd.py index 3259f98..a404e62 100644 --- a/openmp/libompd/gdb-plugin/ompd/ompd.py +++ b/openmp/libompd/gdb-plugin/ompd/ompd.py @@ -11,559 +11,675 @@ from enum import Enum addr_space = None ff = None icv_map = None -ompd_scope_map = {1:'global', 2:'address_space', 3:'thread', 4:'parallel', 5:'implicit_task', 6:'task'} +ompd_scope_map = { + 1: "global", + 2: "address_space", + 3: "thread", + 4: "parallel", + 5: "implicit_task", + 6: "task", +} in_task_function = False + class ompd(gdb.Command): - def __init__(self): - super(ompd, self).__init__('ompd', - gdb.COMMAND_STATUS, - gdb.COMPLETE_NONE, - True) + def __init__(self): + super(ompd, self).__init__("ompd", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE, True) + class ompd_init(gdb.Command): - """Find and initialize ompd library""" - - # first parameter is command-line input, second parameter is gdb-specific data - def __init__(self): - self.__doc__ = 'Find and initialize OMPD library\n usage: ompd init' - super(ompd_init, self).__init__('ompd init', - gdb.COMMAND_DATA) - - def invoke(self, arg, from_tty): - global addr_space - global ff - try: - try: - print(gdb.newest_frame()) - except: - gdb.execute("start") - try: - lib_list = gdb.parse_and_eval("(char**)ompd_dll_locations") - except gdb.error: - raise ValueError("No ompd_dll_locations symbol in execution, make sure to have an OMPD enabled OpenMP runtime"); - - while(gdb.parse_and_eval("(char**)ompd_dll_locations") == False): - gdb.execute("tbreak ompd_dll_locations_valid") - gdb.execute("continue") - - lib_list = gdb.parse_and_eval("(char**)ompd_dll_locations") - - i = 0 - while(lib_list[i]): - ret = ompdModule.ompd_open(lib_list[i].string()) - if ret == -1: - raise ValueError("Handle of OMPD library is not a valid string!") - if ret == -2: - print("ret == -2") - pass # It's ok to fail on dlopen - if ret == -3: - print("ret == -3") - pass # It's ok to fail on dlsym - if ret < -10: - raise ValueError("OMPD error code %i!" % (-10 - ret)) - - if ret > 0: - print("Loaded OMPD lib successfully!") - try: - addr_space = ompd_address_space() - ff = FrameFilter(addr_space) - except: - traceback.print_exc() - return - i = i+1 - - raise ValueError("OMPD library could not be loaded!") - except: - traceback.print_exc() + """Find and initialize ompd library""" + + # first parameter is command-line input, second parameter is gdb-specific data + def __init__(self): + self.__doc__ = "Find and initialize OMPD library\n usage: ompd init" + super(ompd_init, self).__init__("ompd init", gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + global addr_space + global ff + try: + try: + print(gdb.newest_frame()) + except: + gdb.execute("start") + try: + lib_list = gdb.parse_and_eval("(char**)ompd_dll_locations") + except gdb.error: + raise ValueError( + "No ompd_dll_locations symbol in execution, make sure to have an OMPD enabled OpenMP runtime" + ) + + while gdb.parse_and_eval("(char**)ompd_dll_locations") == False: + gdb.execute("tbreak ompd_dll_locations_valid") + gdb.execute("continue") + + lib_list = gdb.parse_and_eval("(char**)ompd_dll_locations") + + i = 0 + while lib_list[i]: + ret = ompdModule.ompd_open(lib_list[i].string()) + if ret == -1: + raise ValueError("Handle of OMPD library is not a valid string!") + if ret == -2: + print("ret == -2") + pass # It's ok to fail on dlopen + if ret == -3: + print("ret == -3") + pass # It's ok to fail on dlsym + if ret < -10: + raise ValueError("OMPD error code %i!" % (-10 - ret)) + + if ret > 0: + print("Loaded OMPD lib successfully!") + try: + addr_space = ompd_address_space() + ff = FrameFilter(addr_space) + except: + traceback.print_exc() + return + i = i + 1 + + raise ValueError("OMPD library could not be loaded!") + except: + traceback.print_exc() + class ompd_threads(gdb.Command): - """Register thread ids of current context""" - def __init__(self): - self.__doc__ = 'Provide information on threads of current context.\n usage: ompd threads' - super(ompd_threads, self).__init__('ompd threads', - gdb.COMMAND_STATUS) - - def invoke(self, arg, from_tty): - global addr_space - if init_error(): - return - addr_space.list_threads(True) + """Register thread ids of current context""" + + def __init__(self): + self.__doc__ = ( + "Provide information on threads of current context.\n usage: ompd threads" + ) + super(ompd_threads, self).__init__("ompd threads", gdb.COMMAND_STATUS) + + def invoke(self, arg, from_tty): + global addr_space + if init_error(): + return + addr_space.list_threads(True) + def print_parallel_region(curr_parallel, team_size): - """Helper function for ompd_parallel_region. To print out the details of the parallel region.""" - for omp_thr in range(team_size): - thread = curr_parallel.get_thread_in_parallel(omp_thr) - ompd_state = str(addr_space.states[thread.get_state()[0]]) - ompd_wait_id = thread.get_state()[1] - task = curr_parallel.get_task_in_parallel(omp_thr) - task_func_addr = task.get_task_function() - # Get the function this addr belongs to - sal = gdb.find_pc_line(task_func_addr) - block = gdb.block_for_pc(task_func_addr) - while block and not block.function: - block = block.superblock - if omp_thr == 0: - print('%6d (master) %-37s %ld 0x%lx %-25s %-17s:%d' % \ - (omp_thr, ompd_state, ompd_wait_id, task_func_addr, \ - block.function.print_name, sal.symtab.filename, sal.line)) - else: - print('%6d %-37s %ld 0x%lx %-25s %-17s:%d' % \ - (omp_thr, ompd_state, ompd_wait_id, task_func_addr, \ - block.function.print_name, sal.symtab.filename, sal.line)) + """Helper function for ompd_parallel_region. To print out the details of the parallel region.""" + for omp_thr in range(team_size): + thread = curr_parallel.get_thread_in_parallel(omp_thr) + ompd_state = str(addr_space.states[thread.get_state()[0]]) + ompd_wait_id = thread.get_state()[1] + task = curr_parallel.get_task_in_parallel(omp_thr) + task_func_addr = task.get_task_function() + # Get the function this addr belongs to + sal = gdb.find_pc_line(task_func_addr) + block = gdb.block_for_pc(task_func_addr) + while block and not block.function: + block = block.superblock + if omp_thr == 0: + print( + "%6d (master) %-37s %ld 0x%lx %-25s %-17s:%d" + % ( + omp_thr, + ompd_state, + ompd_wait_id, + task_func_addr, + block.function.print_name, + sal.symtab.filename, + sal.line, + ) + ) + else: + print( + "%6d %-37s %ld 0x%lx %-25s %-17s:%d" + % ( + omp_thr, + ompd_state, + ompd_wait_id, + task_func_addr, + block.function.print_name, + sal.symtab.filename, + sal.line, + ) + ) + class ompd_parallel_region(gdb.Command): - """Parallel Region Details""" - def __init__(self): - self.__doc__ = 'Display the details of the current and enclosing parallel regions.\n usage: ompd parallel' - super(ompd_parallel_region, self).__init__('ompd parallel', - gdb.COMMAND_STATUS) - - def invoke(self, arg, from_tty): - global addr_space - if init_error(): - return - if addr_space.icv_map is None: - addr_space.get_icv_map() - if addr_space.states is None: - addr_space.enumerate_states() - curr_thread_handle = addr_space.get_curr_thread() - curr_parallel_handle = curr_thread_handle.get_current_parallel_handle() - curr_parallel = ompd_parallel(curr_parallel_handle) - while curr_parallel_handle is not None and curr_parallel is not None: - nest_level = ompdModule.call_ompd_get_icv_from_scope(curr_parallel_handle,\ - addr_space.icv_map['levels-var'][1], addr_space.icv_map['levels-var'][0]) - if nest_level == 0: - break - team_size = ompdModule.call_ompd_get_icv_from_scope(curr_parallel_handle, \ - addr_space.icv_map['team-size-var'][1], \ - addr_space.icv_map['team-size-var'][0]) - print ("") - print ("Parallel Region: Nesting Level %d: Team Size: %d" % (nest_level, team_size)) - print ("================================================") - print ("") - print ("OMP Thread Nbr Thread State Wait Id EntryAddr FuncName File:Line"); - print ("======================================================================================================"); - print_parallel_region(curr_parallel, team_size) - enclosing_parallel = curr_parallel.get_enclosing_parallel() - enclosing_parallel_handle = curr_parallel.get_enclosing_parallel_handle() - curr_parallel = enclosing_parallel - curr_parallel_handle = enclosing_parallel_handle + """Parallel Region Details""" + + def __init__(self): + self.__doc__ = "Display the details of the current and enclosing parallel regions.\n usage: ompd parallel" + super(ompd_parallel_region, self).__init__("ompd parallel", gdb.COMMAND_STATUS) + + def invoke(self, arg, from_tty): + global addr_space + if init_error(): + return + if addr_space.icv_map is None: + addr_space.get_icv_map() + if addr_space.states is None: + addr_space.enumerate_states() + curr_thread_handle = addr_space.get_curr_thread() + curr_parallel_handle = curr_thread_handle.get_current_parallel_handle() + curr_parallel = ompd_parallel(curr_parallel_handle) + while curr_parallel_handle is not None and curr_parallel is not None: + nest_level = ompdModule.call_ompd_get_icv_from_scope( + curr_parallel_handle, + addr_space.icv_map["levels-var"][1], + addr_space.icv_map["levels-var"][0], + ) + if nest_level == 0: + break + team_size = ompdModule.call_ompd_get_icv_from_scope( + curr_parallel_handle, + addr_space.icv_map["team-size-var"][1], + addr_space.icv_map["team-size-var"][0], + ) + print("") + print( + "Parallel Region: Nesting Level %d: Team Size: %d" + % (nest_level, team_size) + ) + print("================================================") + print("") + print( + "OMP Thread Nbr Thread State Wait Id EntryAddr FuncName File:Line" + ) + print( + "======================================================================================================" + ) + print_parallel_region(curr_parallel, team_size) + enclosing_parallel = curr_parallel.get_enclosing_parallel() + enclosing_parallel_handle = curr_parallel.get_enclosing_parallel_handle() + curr_parallel = enclosing_parallel + curr_parallel_handle = enclosing_parallel_handle + class ompd_icvs(gdb.Command): - """ICVs""" - def __init__(self): - self.__doc__ = 'Display the values of the Internal Control Variables.\n usage: ompd icvs' - super(ompd_icvs, self).__init__('ompd icvs', - gdb.COMMAND_STATUS) - - def invoke(self, arg, from_tty): - global addr_space - global ompd_scope_map - if init_error(): - return - curr_thread_handle = addr_space.get_curr_thread() - if addr_space.icv_map is None: - addr_space.get_icv_map() - print("ICV Name Scope Value") - print("===============================================================") - - try: - for icv_name in addr_space.icv_map: - scope = addr_space.icv_map[icv_name][1] - #{1:'global', 2:'address_space', 3:'thread', 4:'parallel', 5:'implicit_task', 6:'task'} - if scope == 2: - handle = addr_space.addr_space - elif scope == 3: - handle = curr_thread_handle.thread_handle - elif scope == 4: - handle = curr_thread_handle.get_current_parallel_handle() - elif scope == 6: - handle = curr_thread_handle.get_current_task_handle() - else: - raise ValueError("Invalid scope") - - if (icv_name == "nthreads-var" or icv_name == "bind-var"): - icv_value = ompdModule.call_ompd_get_icv_from_scope( - handle, scope, addr_space.icv_map[icv_name][0]) - if icv_value is None: - icv_string = ompdModule.call_ompd_get_icv_string_from_scope( \ - handle, scope, addr_space.icv_map[icv_name][0]) - print('%-31s %-26s %s' % (icv_name, ompd_scope_map[scope], icv_string)) - else: - print('%-31s %-26s %d' % (icv_name, ompd_scope_map[scope], icv_value)) - - elif (icv_name == "affinity-format-var" or icv_name == "run-sched-var" or \ - icv_name == "tool-libraries-var" or icv_name == "tool-verbose-init-var"): - icv_string = ompdModule.call_ompd_get_icv_string_from_scope( \ - handle, scope, addr_space.icv_map[icv_name][0]) - print('%-31s %-26s %s' % (icv_name, ompd_scope_map[scope], icv_string)) - else: - icv_value = ompdModule.call_ompd_get_icv_from_scope(handle, \ - scope, addr_space.icv_map[icv_name][0]) - print('%-31s %-26s %d' % (icv_name, ompd_scope_map[scope], icv_value)) - except: - traceback.print_exc() + """ICVs""" + + def __init__(self): + self.__doc__ = ( + "Display the values of the Internal Control Variables.\n usage: ompd icvs" + ) + super(ompd_icvs, self).__init__("ompd icvs", gdb.COMMAND_STATUS) + + def invoke(self, arg, from_tty): + global addr_space + global ompd_scope_map + if init_error(): + return + curr_thread_handle = addr_space.get_curr_thread() + if addr_space.icv_map is None: + addr_space.get_icv_map() + print("ICV Name Scope Value") + print("===============================================================") + + try: + for icv_name in addr_space.icv_map: + scope = addr_space.icv_map[icv_name][1] + # {1:'global', 2:'address_space', 3:'thread', 4:'parallel', 5:'implicit_task', 6:'task'} + if scope == 2: + handle = addr_space.addr_space + elif scope == 3: + handle = curr_thread_handle.thread_handle + elif scope == 4: + handle = curr_thread_handle.get_current_parallel_handle() + elif scope == 6: + handle = curr_thread_handle.get_current_task_handle() + else: + raise ValueError("Invalid scope") + + if icv_name == "nthreads-var" or icv_name == "bind-var": + icv_value = ompdModule.call_ompd_get_icv_from_scope( + handle, scope, addr_space.icv_map[icv_name][0] + ) + if icv_value is None: + icv_string = ompdModule.call_ompd_get_icv_string_from_scope( + handle, scope, addr_space.icv_map[icv_name][0] + ) + print( + "%-31s %-26s %s" + % (icv_name, ompd_scope_map[scope], icv_string) + ) + else: + print( + "%-31s %-26s %d" + % (icv_name, ompd_scope_map[scope], icv_value) + ) + + elif ( + icv_name == "affinity-format-var" + or icv_name == "run-sched-var" + or icv_name == "tool-libraries-var" + or icv_name == "tool-verbose-init-var" + ): + icv_string = ompdModule.call_ompd_get_icv_string_from_scope( + handle, scope, addr_space.icv_map[icv_name][0] + ) + print( + "%-31s %-26s %s" % (icv_name, ompd_scope_map[scope], icv_string) + ) + else: + icv_value = ompdModule.call_ompd_get_icv_from_scope( + handle, scope, addr_space.icv_map[icv_name][0] + ) + print( + "%-31s %-26s %d" % (icv_name, ompd_scope_map[scope], icv_value) + ) + except: + traceback.print_exc() + def curr_thread(): - """Helper function for ompd_step. Returns the thread object for the current thread number.""" - global addr_space - if addr_space is not None: - return addr_space.threads[int(gdb.selected_thread().num)] - return None + """Helper function for ompd_step. Returns the thread object for the current thread number.""" + global addr_space + if addr_space is not None: + return addr_space.threads[int(gdb.selected_thread().num)] + return None -class ompd_test(gdb.Command): - """Test area""" - def __init__(self): - self.__doc__ = 'Test functionalities for correctness\n usage: ompd test' - super(ompd_test, self).__init__('ompd test', - gdb.COMMAND_OBSCURE) - - def invoke(self, arg, from_tty): - global addr_space - if init_error(): - return - # get task function for current task of current thread - try: - current_thread = int(gdb.selected_thread().num) - current_thread_obj = addr_space.threads[current_thread] - task_function = current_thread_obj.get_current_task().get_task_function() - print("bt value:", int("0x0000000000400b6c",0)) - print("get_task_function value:", task_function) - - # get task function of implicit task in current parallel region for current thread - current_parallel_obj = current_thread_obj.get_current_parallel() - task_in_parallel = current_parallel_obj.get_task_in_parallel(current_thread) - task_function_in_parallel = task_in_parallel.get_task_function() - print("task_function_in_parallel:", task_function_in_parallel) - except: - print('Task function value not found for this thread') - -class ompdtestapi (gdb.Command): - """ To test API's return code """ - def __init__(self): - self.__doc__ = 'Test OMPD tool Interface APIs.\nUsage: ompdtestapi <api name>' - super (ompdtestapi, self).__init__('ompdtestapi', gdb.COMMAND_OBSCURE) - - def invoke (self, arg, from_tty): - global addr_space - if init_error(): - print ("Error in Initialization."); - return - if not arg: - print ("No API provided to test, eg: ompdtestapi ompd_initialize") - - if arg == "ompd_get_thread_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - ompdModule.test_ompd_get_thread_handle(addr_handle, threadId) - elif arg == "ompd_get_curr_parallel_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - ompdModule.test_ompd_get_curr_parallel_handle(thread_handle) - elif arg == "ompd_get_thread_in_parallel": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - ompdModule.test_ompd_get_thread_in_parallel(parallel_handle) - elif arg == "ompd_thread_handle_compare": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - thread_handle1 = ompdModule.call_ompd_get_thread_in_parallel(parallel_handle, 1); - thread_handle2 = ompdModule.call_ompd_get_thread_in_parallel(parallel_handle, 2); - ompdModule.test_ompd_thread_handle_compare(thread_handle1, thread_handle1) - ompdModule.test_ompd_thread_handle_compare(thread_handle1, thread_handle2) - elif arg == "ompd_get_thread_id": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - ompdModule.test_ompd_get_thread_id(thread_handle) - elif arg == "ompd_rel_thread_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - ompdModule.test_ompd_rel_thread_handle(thread_handle) - elif arg == "ompd_get_enclosing_parallel_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - ompdModule.test_ompd_get_enclosing_parallel_handle(parallel_handle) - elif arg == "ompd_parallel_handle_compare": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle1 = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - parallel_handle2 = ompdModule.call_ompd_get_enclosing_parallel_handle(parallel_handle1) - ompdModule.test_ompd_parallel_handle_compare(parallel_handle1, parallel_handle1) - ompdModule.test_ompd_parallel_handle_compare(parallel_handle1, parallel_handle2) - elif arg == "ompd_rel_parallel_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - ompdModule.test_ompd_rel_parallel_handle(parallel_handle) - elif arg == "ompd_initialize": - ompdModule.test_ompd_initialize() - elif arg == "ompd_get_api_version": - ompdModule.test_ompd_get_api_version() - elif arg == "ompd_get_version_string": - ompdModule.test_ompd_get_version_string() - elif arg == "ompd_finalize": - ompdModule.test_ompd_finalize() - elif arg == "ompd_process_initialize": - ompdModule.call_ompd_initialize() - ompdModule.test_ompd_process_initialize() - elif arg == "ompd_device_initialize": - ompdModule.test_ompd_device_initialize() - elif arg == "ompd_rel_address_space_handle": - ompdModule.test_ompd_rel_address_space_handle() - elif arg == "ompd_get_omp_version": - addr_handle = addr_space.addr_space - ompdModule.test_ompd_get_omp_version(addr_handle) - elif arg == "ompd_get_omp_version_string": - addr_handle = addr_space.addr_space - ompdModule.test_ompd_get_omp_version_string(addr_handle) - elif arg == "ompd_get_curr_task_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - ompdModule.test_ompd_get_curr_task_handle(thread_handle) - elif arg == "ompd_get_task_parallel_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_get_task_parallel_handle(task_handle) - elif arg == "ompd_get_generating_task_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_get_generating_task_handle(task_handle) - elif arg == "ompd_get_scheduling_task_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_get_scheduling_task_handle(task_handle) - elif arg == "ompd_get_task_in_parallel": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - ompdModule.test_ompd_get_task_in_parallel(parallel_handle) - elif arg == "ompd_rel_task_handle": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_rel_task_handle(task_handle) - elif arg == "ompd_task_handle_compare": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle1 = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - task_handle2 = ompdModule.call_ompd_get_generating_task_handle(task_handle1) - ompdModule.test_ompd_task_handle_compare(task_handle1, task_handle2) - ompdModule.test_ompd_task_handle_compare(task_handle2, task_handle1) - elif arg == "ompd_get_task_function": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_get_task_function(task_handle) - elif arg == "ompd_get_task_frame": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_get_task_frame(task_handle) - elif arg == "ompd_get_state": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - ompdModule.test_ompd_get_state(thread_handle) - elif arg == "ompd_get_display_control_vars": - addr_handle = addr_space.addr_space - ompdModule.test_ompd_get_display_control_vars(addr_handle) - elif arg == "ompd_rel_display_control_vars": - ompdModule.test_ompd_rel_display_control_vars() - elif arg == "ompd_enumerate_icvs": - addr_handle = addr_space.addr_space - ompdModule.test_ompd_enumerate_icvs(addr_handle) - elif arg== "ompd_get_icv_from_scope": - addr_handle = addr_space.addr_space - threadId = gdb.selected_thread().ptid[1] - thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) - parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(thread_handle) - task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) - ompdModule.test_ompd_get_icv_from_scope_with_addr_handle(addr_handle) - ompdModule.test_ompd_get_icv_from_scope_with_thread_handle(thread_handle) - ompdModule.test_ompd_get_icv_from_scope_with_parallel_handle(parallel_handle) - ompdModule.test_ompd_get_icv_from_scope_with_task_handle(task_handle) - elif arg == "ompd_get_icv_string_from_scope": - addr_handle = addr_space.addr_space - ompdModule.test_ompd_get_icv_string_from_scope(addr_handle) - elif arg == "ompd_get_tool_data": - ompdModule.test_ompd_get_tool_data() - elif arg == "ompd_enumerate_states": - ompdModule.test_ompd_enumerate_states() - else: - print ("Invalid API.") +class ompd_test(gdb.Command): + """Test area""" + + def __init__(self): + self.__doc__ = "Test functionalities for correctness\n usage: ompd test" + super(ompd_test, self).__init__("ompd test", gdb.COMMAND_OBSCURE) + + def invoke(self, arg, from_tty): + global addr_space + if init_error(): + return + # get task function for current task of current thread + try: + current_thread = int(gdb.selected_thread().num) + current_thread_obj = addr_space.threads[current_thread] + task_function = current_thread_obj.get_current_task().get_task_function() + print("bt value:", int("0x0000000000400b6c", 0)) + print("get_task_function value:", task_function) + + # get task function of implicit task in current parallel region for current thread + current_parallel_obj = current_thread_obj.get_current_parallel() + task_in_parallel = current_parallel_obj.get_task_in_parallel(current_thread) + task_function_in_parallel = task_in_parallel.get_task_function() + print("task_function_in_parallel:", task_function_in_parallel) + except: + print("Task function value not found for this thread") + + +class ompdtestapi(gdb.Command): + """To test API's return code""" + + def __init__(self): + self.__doc__ = "Test OMPD tool Interface APIs.\nUsage: ompdtestapi <api name>" + super(ompdtestapi, self).__init__("ompdtestapi", gdb.COMMAND_OBSCURE) + + def invoke(self, arg, from_tty): + global addr_space + if init_error(): + print("Error in Initialization.") + return + if not arg: + print("No API provided to test, eg: ompdtestapi ompd_initialize") + + if arg == "ompd_get_thread_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + ompdModule.test_ompd_get_thread_handle(addr_handle, threadId) + elif arg == "ompd_get_curr_parallel_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + ompdModule.test_ompd_get_curr_parallel_handle(thread_handle) + elif arg == "ompd_get_thread_in_parallel": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + ompdModule.test_ompd_get_thread_in_parallel(parallel_handle) + elif arg == "ompd_thread_handle_compare": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + thread_handle1 = ompdModule.call_ompd_get_thread_in_parallel( + parallel_handle, 1 + ) + thread_handle2 = ompdModule.call_ompd_get_thread_in_parallel( + parallel_handle, 2 + ) + ompdModule.test_ompd_thread_handle_compare(thread_handle1, thread_handle1) + ompdModule.test_ompd_thread_handle_compare(thread_handle1, thread_handle2) + elif arg == "ompd_get_thread_id": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + ompdModule.test_ompd_get_thread_id(thread_handle) + elif arg == "ompd_rel_thread_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + ompdModule.test_ompd_rel_thread_handle(thread_handle) + elif arg == "ompd_get_enclosing_parallel_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + ompdModule.test_ompd_get_enclosing_parallel_handle(parallel_handle) + elif arg == "ompd_parallel_handle_compare": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle1 = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + parallel_handle2 = ompdModule.call_ompd_get_enclosing_parallel_handle( + parallel_handle1 + ) + ompdModule.test_ompd_parallel_handle_compare( + parallel_handle1, parallel_handle1 + ) + ompdModule.test_ompd_parallel_handle_compare( + parallel_handle1, parallel_handle2 + ) + elif arg == "ompd_rel_parallel_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + ompdModule.test_ompd_rel_parallel_handle(parallel_handle) + elif arg == "ompd_initialize": + ompdModule.test_ompd_initialize() + elif arg == "ompd_get_api_version": + ompdModule.test_ompd_get_api_version() + elif arg == "ompd_get_version_string": + ompdModule.test_ompd_get_version_string() + elif arg == "ompd_finalize": + ompdModule.test_ompd_finalize() + elif arg == "ompd_process_initialize": + ompdModule.call_ompd_initialize() + ompdModule.test_ompd_process_initialize() + elif arg == "ompd_device_initialize": + ompdModule.test_ompd_device_initialize() + elif arg == "ompd_rel_address_space_handle": + ompdModule.test_ompd_rel_address_space_handle() + elif arg == "ompd_get_omp_version": + addr_handle = addr_space.addr_space + ompdModule.test_ompd_get_omp_version(addr_handle) + elif arg == "ompd_get_omp_version_string": + addr_handle = addr_space.addr_space + ompdModule.test_ompd_get_omp_version_string(addr_handle) + elif arg == "ompd_get_curr_task_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + ompdModule.test_ompd_get_curr_task_handle(thread_handle) + elif arg == "ompd_get_task_parallel_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_get_task_parallel_handle(task_handle) + elif arg == "ompd_get_generating_task_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_get_generating_task_handle(task_handle) + elif arg == "ompd_get_scheduling_task_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_get_scheduling_task_handle(task_handle) + elif arg == "ompd_get_task_in_parallel": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + ompdModule.test_ompd_get_task_in_parallel(parallel_handle) + elif arg == "ompd_rel_task_handle": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_rel_task_handle(task_handle) + elif arg == "ompd_task_handle_compare": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle1 = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + task_handle2 = ompdModule.call_ompd_get_generating_task_handle(task_handle1) + ompdModule.test_ompd_task_handle_compare(task_handle1, task_handle2) + ompdModule.test_ompd_task_handle_compare(task_handle2, task_handle1) + elif arg == "ompd_get_task_function": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_get_task_function(task_handle) + elif arg == "ompd_get_task_frame": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_get_task_frame(task_handle) + elif arg == "ompd_get_state": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + ompdModule.test_ompd_get_state(thread_handle) + elif arg == "ompd_get_display_control_vars": + addr_handle = addr_space.addr_space + ompdModule.test_ompd_get_display_control_vars(addr_handle) + elif arg == "ompd_rel_display_control_vars": + ompdModule.test_ompd_rel_display_control_vars() + elif arg == "ompd_enumerate_icvs": + addr_handle = addr_space.addr_space + ompdModule.test_ompd_enumerate_icvs(addr_handle) + elif arg == "ompd_get_icv_from_scope": + addr_handle = addr_space.addr_space + threadId = gdb.selected_thread().ptid[1] + thread_handle = ompdModule.get_thread_handle(threadId, addr_handle) + parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + thread_handle + ) + task_handle = ompdModule.call_ompd_get_curr_task_handle(thread_handle) + ompdModule.test_ompd_get_icv_from_scope_with_addr_handle(addr_handle) + ompdModule.test_ompd_get_icv_from_scope_with_thread_handle(thread_handle) + ompdModule.test_ompd_get_icv_from_scope_with_parallel_handle( + parallel_handle + ) + ompdModule.test_ompd_get_icv_from_scope_with_task_handle(task_handle) + elif arg == "ompd_get_icv_string_from_scope": + addr_handle = addr_space.addr_space + ompdModule.test_ompd_get_icv_string_from_scope(addr_handle) + elif arg == "ompd_get_tool_data": + ompdModule.test_ompd_get_tool_data() + elif arg == "ompd_enumerate_states": + ompdModule.test_ompd_enumerate_states() + else: + print("Invalid API.") class ompd_bt(gdb.Command): - """Turn filter for 'bt' on/off for output to only contain frames relevant to the application or all frames.""" - def __init__(self): - self.__doc__ = 'Turn filter for "bt" output on or off. Specify "on continued" option to trace worker threads back to master threads.\n usage: ompd bt on|on continued|off' - super(ompd_bt, self).__init__('ompd bt', - gdb.COMMAND_STACK) - - def invoke(self, arg, from_tty): - global ff - global addr_space - global icv_map - global ompd_scope_map - if init_error(): - return - if icv_map is None: - icv_map = {} - current = 0 - more = 1 - while more > 0: - tup = ompdModule.call_ompd_enumerate_icvs(addr_space.addr_space, current) - (current, next_icv, next_scope, more) = tup - icv_map[next_icv] = (current, next_scope, ompd_scope_map[next_scope]) - print('Initialized ICV map successfully for filtering "bt".') - - arg_list = gdb.string_to_argv(arg) - if len(arg_list) == 0: - print('When calling "ompd bt", you must either specify "on", "on continued" or "off". Check "help ompd".') - elif len(arg_list) == 1 and arg_list[0] == 'on': - addr_space.list_threads(False) - ff.set_switch(True) - ff.set_switch_continue(False) - elif arg_list[0] == 'on' and arg_list[1] == 'continued': - ff.set_switch(True) - ff.set_switch_continue(True) - elif len(arg_list) == 1 and arg_list[0] == 'off': - ff.set_switch(False) - ff.set_switch_continue(False) - else: - print('When calling "ompd bt", you must either specify "on", "on continued" or "off". Check "help ompd".') + """Turn filter for 'bt' on/off for output to only contain frames relevant to the application or all frames.""" + + def __init__(self): + self.__doc__ = 'Turn filter for "bt" output on or off. Specify "on continued" option to trace worker threads back to master threads.\n usage: ompd bt on|on continued|off' + super(ompd_bt, self).__init__("ompd bt", gdb.COMMAND_STACK) + + def invoke(self, arg, from_tty): + global ff + global addr_space + global icv_map + global ompd_scope_map + if init_error(): + return + if icv_map is None: + icv_map = {} + current = 0 + more = 1 + while more > 0: + tup = ompdModule.call_ompd_enumerate_icvs( + addr_space.addr_space, current + ) + (current, next_icv, next_scope, more) = tup + icv_map[next_icv] = (current, next_scope, ompd_scope_map[next_scope]) + print('Initialized ICV map successfully for filtering "bt".') + + arg_list = gdb.string_to_argv(arg) + if len(arg_list) == 0: + print( + 'When calling "ompd bt", you must either specify "on", "on continued" or "off". Check "help ompd".' + ) + elif len(arg_list) == 1 and arg_list[0] == "on": + addr_space.list_threads(False) + ff.set_switch(True) + ff.set_switch_continue(False) + elif arg_list[0] == "on" and arg_list[1] == "continued": + ff.set_switch(True) + ff.set_switch_continue(True) + elif len(arg_list) == 1 and arg_list[0] == "off": + ff.set_switch(False) + ff.set_switch_continue(False) + else: + print( + 'When calling "ompd bt", you must either specify "on", "on continued" or "off". Check "help ompd".' + ) + # TODO: remove class ompd_taskframes(gdb.Command): - """Prints task handles for relevant task frames. Meant for debugging.""" - def __init__(self): - self.__doc__ = 'Prints list of tasks.\nUsage: ompd taskframes' - super(ompd_taskframes, self).__init__('ompd taskframes', - gdb.COMMAND_STACK) - - def invoke(self, arg, from_tty): - global addr_space - if init_error(): - return - frame = gdb.newest_frame() - while(frame): - print (frame.read_register('sp')) - frame = frame.older() - curr_task_handle = None - if(addr_space.threads and addr_space.threads.get(gdb.selected_thread().num)): - curr_thread_handle = curr_thread().thread_handle - curr_task_handle = ompdModule.call_ompd_get_curr_task_handle(curr_thread_handle) - if(not curr_task_handle): - return None - prev_frames = None - try: - while(1): - frames_with_flags = ompdModule.call_ompd_get_task_frame(curr_task_handle) - frames = (frames_with_flags[0], frames_with_flags[3]) - if(prev_frames == frames): - break - if(not isinstance(frames,tuple)): - break - (ompd_enter_frame, ompd_exit_frame) = frames - print(hex(ompd_enter_frame), hex(ompd_exit_frame)) - curr_task_handle = ompdModule.call_ompd_get_scheduling_task_handle(curr_task_handle) - prev_frames = frames - if(not curr_task_handle): - break - except: - traceback.print_exc() + """Prints task handles for relevant task frames. Meant for debugging.""" + + def __init__(self): + self.__doc__ = "Prints list of tasks.\nUsage: ompd taskframes" + super(ompd_taskframes, self).__init__("ompd taskframes", gdb.COMMAND_STACK) + + def invoke(self, arg, from_tty): + global addr_space + if init_error(): + return + frame = gdb.newest_frame() + while frame: + print(frame.read_register("sp")) + frame = frame.older() + curr_task_handle = None + if addr_space.threads and addr_space.threads.get(gdb.selected_thread().num): + curr_thread_handle = curr_thread().thread_handle + curr_task_handle = ompdModule.call_ompd_get_curr_task_handle( + curr_thread_handle + ) + if not curr_task_handle: + return None + prev_frames = None + try: + while 1: + frames_with_flags = ompdModule.call_ompd_get_task_frame( + curr_task_handle + ) + frames = (frames_with_flags[0], frames_with_flags[3]) + if prev_frames == frames: + break + if not isinstance(frames, tuple): + break + (ompd_enter_frame, ompd_exit_frame) = frames + print(hex(ompd_enter_frame), hex(ompd_exit_frame)) + curr_task_handle = ompdModule.call_ompd_get_scheduling_task_handle( + curr_task_handle + ) + prev_frames = frames + if not curr_task_handle: + break + except: + traceback.print_exc() + def print_and_exec(string): - """Helper function for ompd_step. Executes the given command in GDB and prints it.""" - print(string) - gdb.execute(string) + """Helper function for ompd_step. Executes the given command in GDB and prints it.""" + print(string) + gdb.execute(string) + class TempFrameFunctionBp(gdb.Breakpoint): - """Helper class for ompd_step. Defines stop function for breakpoint on frame function.""" - def stop(self): - global in_task_function - in_task_function = True - self.enabled = False + """Helper class for ompd_step. Defines stop function for breakpoint on frame function.""" + + def stop(self): + global in_task_function + in_task_function = True + self.enabled = False + class ompd_step(gdb.Command): - """Executes 'step' and skips frames irrelevant to the application / the ones without debug information.""" - def __init__(self): - self.__doc__ = 'Executes "step" and skips runtime frames as much as possible.' - super(ompd_step, self).__init__('ompd step', gdb.COMMAND_STACK) - - class TaskBeginBp(gdb.Breakpoint): - """Helper class. Defines stop function for breakpoint ompd_bp_task_begin.""" - def stop(self): - try: - code_line = curr_thread().get_current_task().get_task_function() - frame_fct_bp = TempFrameFunctionBp(('*%i' % code_line), temporary=True, internal=True) - frame_fct_bp.thread = self.thread - return False - except: - return False - - def invoke(self, arg, from_tty): - global in_task_function - if init_error(): - return - tbp = self.TaskBeginBp('ompd_bp_task_begin', temporary=True, internal=True) - tbp.thread = int(gdb.selected_thread().num) - print_and_exec('step') - while gdb.selected_frame().find_sal().symtab is None: - if not in_task_function: - print_and_exec('finish') - else: - print_and_exec('si') + """Executes 'step' and skips frames irrelevant to the application / the ones without debug information.""" + + def __init__(self): + self.__doc__ = 'Executes "step" and skips runtime frames as much as possible.' + super(ompd_step, self).__init__("ompd step", gdb.COMMAND_STACK) + + class TaskBeginBp(gdb.Breakpoint): + """Helper class. Defines stop function for breakpoint ompd_bp_task_begin.""" + + def stop(self): + try: + code_line = curr_thread().get_current_task().get_task_function() + frame_fct_bp = TempFrameFunctionBp( + ("*%i" % code_line), temporary=True, internal=True + ) + frame_fct_bp.thread = self.thread + return False + except: + return False + + def invoke(self, arg, from_tty): + global in_task_function + if init_error(): + return + tbp = self.TaskBeginBp("ompd_bp_task_begin", temporary=True, internal=True) + tbp.thread = int(gdb.selected_thread().num) + print_and_exec("step") + while gdb.selected_frame().find_sal().symtab is None: + if not in_task_function: + print_and_exec("finish") + else: + print_and_exec("si") + def init_error(): - global addr_space - if (gdb.selected_thread() is None) or (addr_space is None) or (not addr_space): - print("Run 'ompd init' before running any of the ompd commands") - return True - return False + global addr_space + if (gdb.selected_thread() is None) or (addr_space is None) or (not addr_space): + print("Run 'ompd init' before running any of the ompd commands") + return True + return False + def main(): - ompd() - ompd_init() - ompd_threads() - ompd_icvs() - ompd_parallel_region() - ompd_test() - ompdtestapi() - ompd_taskframes() - ompd_bt() - ompd_step() + ompd() + ompd_init() + ompd_threads() + ompd_icvs() + ompd_parallel_region() + ompd_test() + ompdtestapi() + ompd_taskframes() + ompd_bt() + ompd_step() + if __name__ == "__main__": - try: - main() - except: - traceback.print_exc() + try: + main() + except: + traceback.print_exc() # NOTE: test code using: # OMP_NUM_THREADS=... gdb a.out -x ../../projects/gdb_plugin/gdb-ompd/__init__.py diff --git a/openmp/libompd/gdb-plugin/ompd/ompd_address_space.py b/openmp/libompd/gdb-plugin/ompd/ompd_address_space.py index 8b8f5bb..3c4f357 100644 --- a/openmp/libompd/gdb-plugin/ompd/ompd_address_space.py +++ b/openmp/libompd/gdb-plugin/ompd/ompd_address_space.py @@ -6,309 +6,464 @@ import sys import traceback from enum import Enum + class ompd_scope(Enum): - ompd_scope_global = 1 - ompd_scope_address_space = 2 - ompd_scope_thread = 3 - ompd_scope_parallel = 4 - ompd_scope_implicit_task = 5 - ompd_scope_task = 6 + ompd_scope_global = 1 + ompd_scope_address_space = 2 + ompd_scope_thread = 3 + ompd_scope_parallel = 4 + ompd_scope_implicit_task = 5 + ompd_scope_task = 6 + class ompd_address_space(object): - - def __init__(self): - """Initializes an ompd_address_space object by calling ompd_initialize - in ompdModule.c - """ - self.addr_space = ompdModule.call_ompd_initialize() - # maps thread_num (thread id given by gdb) to ompd_thread object with thread handle - self.threads = {} - self.states = None - self.icv_map = None - self.ompd_tool_test_bp = None - self.scope_map = {1:'global', 2:'address_space', 3:'thread', 4:'parallel', 5:'implicit_task', 6:'task'} - self.sched_map = {1:'static', 2:'dynamic', 3:'guided', 4:'auto'} - gdb.events.stop.connect(self.handle_stop_event) - self.new_thread_breakpoint = gdb.Breakpoint("ompd_bp_thread_begin", internal=True) - tool_break_symbol = gdb.lookup_global_symbol("ompd_tool_break") - if (tool_break_symbol is not None): - self.ompd_tool_test_bp = gdb.Breakpoint("ompd_tool_break", internal=True) - - def handle_stop_event(self, event): - """Sets a breakpoint at different events, e.g. when a new OpenMP - thread is created. - """ - if (isinstance(event, gdb.BreakpointEvent)): - # check if breakpoint has already been hit - if (self.new_thread_breakpoint in event.breakpoints): - self.add_thread() - gdb.execute('continue') - return - elif (self.ompd_tool_test_bp is not None and self.ompd_tool_test_bp in event.breakpoints): - try: - self.compare_ompt_data() - gdb.execute('continue') - except(): - traceback.print_exc() - elif (isinstance(event, gdb.SignalEvent)): - # TODO: what do we need to do on SIGNALS? - pass - else: - # TODO: probably not possible? - pass - - def get_icv_map(self): - """Fills ICV map. - """ - self.icv_map = {} - current = 0 - more = 1 - while more > 0: - tup = ompdModule.call_ompd_enumerate_icvs(self.addr_space, current) - (current, next_icv, next_scope, more) = tup - self.icv_map[next_icv] = (current, next_scope, self.scope_map[next_scope]) - print('Initialized ICV map successfully for checking OMP API values.') - - def compare_ompt_data(self): - """Compares OMPT tool data about parallel region to data returned by OMPD functions. - """ - # make sure all threads and states are set - self.list_threads(False) - - thread_id = gdb.selected_thread().ptid[1] - curr_thread = self.get_curr_thread() - - # check if current thread is LWP thread; return if "ompd_rc_unavailable" - thread_handle = ompdModule.get_thread_handle(thread_id, self.addr_space) - if thread_handle == -1: - print("Skipping OMPT-OMPD checks for non-LWP thread.") - return - - print('Comparing OMPT data to OMPD data...') - field_names = [i.name for i in gdb.parse_and_eval('thread_data').type.fields()] - thread_data = gdb.parse_and_eval('thread_data') - - if self.icv_map is None: - self.get_icv_map() - - # compare state values - if 'ompt_state' in field_names: - if self.states is None: - self.enumerate_states() - ompt_state = str(thread_data['ompt_state']) - ompd_state = str(self.states[curr_thread.get_state()[0]]) - if ompt_state != ompd_state: - print('OMPT-OMPD mismatch: ompt_state (%s) does not match OMPD state (%s)!' % (ompt_state, ompd_state)) - - # compare wait_id values - if 'ompt_wait_id' in field_names: - ompt_wait_id = thread_data['ompt_wait_id'] - ompd_wait_id = curr_thread.get_state()[1] - if ompt_wait_id != ompd_wait_id: - print('OMPT-OMPD mismatch: ompt_wait_id (%d) does not match OMPD wait id (%d)!' % (ompt_wait_id, ompd_wait_id)) - - # compare thread id - if 'omp_thread_num' in field_names and 'thread-num-var' in self.icv_map: - ompt_thread_num = thread_data['omp_thread_num'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.thread_handle, self.icv_map['thread-num-var'][1], self.icv_map['thread-num-var'][0]) - if ompt_thread_num != icv_value: - print('OMPT-OMPD mismatch: omp_thread_num (%d) does not match OMPD thread num according to ICVs (%d)!' % (ompt_thread_num, icv_value)) - - # compare thread data - if 'ompt_thread_data' in field_names: - ompt_thread_data = thread_data['ompt_thread_data'].dereference()['value'] - ompd_value = ompdModule.call_ompd_get_tool_data(3, curr_thread.thread_handle)[0] - if ompt_thread_data != ompd_value: - print('OMPT-OMPD mismatch: value of ompt_thread_data (%d) does not match that of OMPD data union (%d)!' % (ompt_thread_data, ompd_value)) - - # compare number of threads - if 'omp_num_threads' in field_names and 'team-size-var' in self.icv_map: - ompt_num_threads = thread_data['omp_num_threads'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.get_current_parallel_handle(), self.icv_map['team-size-var'][1], self.icv_map['team-size-var'][0]) - if ompt_num_threads != icv_value: - print('OMPT-OMPD mismatch: omp_num_threads (%d) does not match OMPD num threads according to ICVs (%d)!' % (ompt_num_threads, icv_value)) - - # compare omp level - if 'omp_level' in field_names and 'levels-var' in self.icv_map: - ompt_levels = thread_data['omp_level'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.get_current_parallel_handle(), self.icv_map['levels-var'][1], self.icv_map['levels-var'][0]) - if ompt_levels != icv_value: - print('OMPT-OMPD mismatch: omp_level (%d) does not match OMPD levels according to ICVs (%d)!' % (ompt_levels, icv_value)) - - # compare active level - if 'omp_active_level' in field_names and 'active-levels-var' in self.icv_map: - ompt_active_levels = thread_data['omp_active_level'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.get_current_parallel_handle(), self.icv_map['active-levels-var'][1], self.icv_map['active-levels-var'][0]) - if ompt_active_levels != icv_value: - print('OMPT-OMPD mismatch: active levels (%d) do not match active levels according to ICVs (%d)!' % (ompt_active_levels, icv_value)) - - # compare parallel data - if 'ompt_parallel_data' in field_names: - ompt_parallel_data = thread_data['ompt_parallel_data'].dereference()['value'] - current_parallel_handle = curr_thread.get_current_parallel_handle() - ompd_value = ompdModule.call_ompd_get_tool_data(4, current_parallel_handle)[0] - if ompt_parallel_data != ompd_value: - print('OMPT-OMPD mismatch: value of ompt_parallel_data (%d) does not match that of OMPD data union (%d)!' % (ompt_parallel_data, ompd_value)) - - # compare max threads - if 'omp_max_threads' in field_names and 'nthreads-var' in self.icv_map: - ompt_max_threads = thread_data['omp_max_threads'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.thread_handle, self.icv_map['nthreads-var'][1], self.icv_map['nthreads-var'][0]) - if icv_value is None: - icv_string = ompdModule.call_ompd_get_icv_string_from_scope(curr_thread.thread_handle, self.icv_map['nthreads-var'][1], self.icv_map['nthreads-var'][0]) - if icv_string is None: - print('OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (None Object)' % (ompt_max_threads)) - else: - if ompt_max_threads != int(icv_string.split(',')[0]): - print('OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!' % (ompt_max_threads, int(icv_string.split(',')[0]))) - else: - if ompt_max_threads != icv_value: - print('OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!' % (ompt_max_threads, icv_value)) - - # compare omp_parallel - # NOTE: omp_parallel = true if active-levels-var > 0 - if 'omp_parallel' in field_names: - ompt_parallel = thread_data['omp_parallel'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.get_current_parallel_handle(), self.icv_map['active-levels-var'][1], self.icv_map['active-levels-var'][0]) - if ompt_parallel == 1 and icv_value <= 0 or ompt_parallel == 0 and icv_value > 0: - print('OMPT-OMPD mismatch: ompt_parallel (%d) does not match OMPD parallel according to ICVs (%d)!' % (ompt_parallel, icv_value)) - - # compare omp_final - if 'omp_final' in field_names and 'final-task-var' in self.icv_map: - ompt_final = thread_data['omp_final'] - current_task_handle = curr_thread.get_current_task_handle() - icv_value = ompdModule.call_ompd_get_icv_from_scope(current_task_handle, self.icv_map['final-task-var'][1], self.icv_map['final-task-var'][0]) - if icv_value != ompt_final: - print('OMPT-OMPD mismatch: omp_final (%d) does not match OMPD final according to ICVs (%d)!' % (ompt_final, icv_value)) - - # compare omp_dynamic - if 'omp_dynamic' in field_names and 'dyn-var' in self.icv_map: - ompt_dynamic = thread_data['omp_dynamic'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.thread_handle, self.icv_map['dyn-var'][1], self.icv_map['dyn-var'][0]) - if icv_value != ompt_dynamic: - print('OMPT-OMPD mismatch: omp_dynamic (%d) does not match OMPD dynamic according to ICVs (%d)!' % (ompt_dynamic, icv_value)) - - # compare omp_max_active_levels - if 'omp_max_active_levels' in field_names and 'max-active-levels-var' in self.icv_map: - ompt_max_active_levels = thread_data['omp_max_active_levels'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.get_current_task_handle(), self.icv_map['max-active-levels-var'][1], self.icv_map['max-active-levels-var'][0]) - if ompt_max_active_levels != icv_value: - print('OMPT-OMPD mismatch: omp_max_active_levels (%d) does not match OMPD max active levels (%d)!' % (ompt_max_active_levels, icv_value)) - + def __init__(self): + """Initializes an ompd_address_space object by calling ompd_initialize + in ompdModule.c + """ + self.addr_space = ompdModule.call_ompd_initialize() + # maps thread_num (thread id given by gdb) to ompd_thread object with thread handle + self.threads = {} + self.states = None + self.icv_map = None + self.ompd_tool_test_bp = None + self.scope_map = { + 1: "global", + 2: "address_space", + 3: "thread", + 4: "parallel", + 5: "implicit_task", + 6: "task", + } + self.sched_map = {1: "static", 2: "dynamic", 3: "guided", 4: "auto"} + gdb.events.stop.connect(self.handle_stop_event) + self.new_thread_breakpoint = gdb.Breakpoint( + "ompd_bp_thread_begin", internal=True + ) + tool_break_symbol = gdb.lookup_global_symbol("ompd_tool_break") + if tool_break_symbol is not None: + self.ompd_tool_test_bp = gdb.Breakpoint("ompd_tool_break", internal=True) + + def handle_stop_event(self, event): + """Sets a breakpoint at different events, e.g. when a new OpenMP + thread is created. + """ + if isinstance(event, gdb.BreakpointEvent): + # check if breakpoint has already been hit + if self.new_thread_breakpoint in event.breakpoints: + self.add_thread() + gdb.execute("continue") + return + elif ( + self.ompd_tool_test_bp is not None + and self.ompd_tool_test_bp in event.breakpoints + ): + try: + self.compare_ompt_data() + gdb.execute("continue") + except (): + traceback.print_exc() + elif isinstance(event, gdb.SignalEvent): + # TODO: what do we need to do on SIGNALS? + pass + else: + # TODO: probably not possible? + pass + + def get_icv_map(self): + """Fills ICV map.""" + self.icv_map = {} + current = 0 + more = 1 + while more > 0: + tup = ompdModule.call_ompd_enumerate_icvs(self.addr_space, current) + (current, next_icv, next_scope, more) = tup + self.icv_map[next_icv] = (current, next_scope, self.scope_map[next_scope]) + print("Initialized ICV map successfully for checking OMP API values.") + + def compare_ompt_data(self): + """Compares OMPT tool data about parallel region to data returned by OMPD functions.""" + # make sure all threads and states are set + self.list_threads(False) + + thread_id = gdb.selected_thread().ptid[1] + curr_thread = self.get_curr_thread() + + # check if current thread is LWP thread; return if "ompd_rc_unavailable" + thread_handle = ompdModule.get_thread_handle(thread_id, self.addr_space) + if thread_handle == -1: + print("Skipping OMPT-OMPD checks for non-LWP thread.") + return + + print("Comparing OMPT data to OMPD data...") + field_names = [i.name for i in gdb.parse_and_eval("thread_data").type.fields()] + thread_data = gdb.parse_and_eval("thread_data") + + if self.icv_map is None: + self.get_icv_map() + + # compare state values + if "ompt_state" in field_names: + if self.states is None: + self.enumerate_states() + ompt_state = str(thread_data["ompt_state"]) + ompd_state = str(self.states[curr_thread.get_state()[0]]) + if ompt_state != ompd_state: + print( + "OMPT-OMPD mismatch: ompt_state (%s) does not match OMPD state (%s)!" + % (ompt_state, ompd_state) + ) + + # compare wait_id values + if "ompt_wait_id" in field_names: + ompt_wait_id = thread_data["ompt_wait_id"] + ompd_wait_id = curr_thread.get_state()[1] + if ompt_wait_id != ompd_wait_id: + print( + "OMPT-OMPD mismatch: ompt_wait_id (%d) does not match OMPD wait id (%d)!" + % (ompt_wait_id, ompd_wait_id) + ) + + # compare thread id + if "omp_thread_num" in field_names and "thread-num-var" in self.icv_map: + ompt_thread_num = thread_data["omp_thread_num"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.thread_handle, + self.icv_map["thread-num-var"][1], + self.icv_map["thread-num-var"][0], + ) + if ompt_thread_num != icv_value: + print( + "OMPT-OMPD mismatch: omp_thread_num (%d) does not match OMPD thread num according to ICVs (%d)!" + % (ompt_thread_num, icv_value) + ) + + # compare thread data + if "ompt_thread_data" in field_names: + ompt_thread_data = thread_data["ompt_thread_data"].dereference()["value"] + ompd_value = ompdModule.call_ompd_get_tool_data( + 3, curr_thread.thread_handle + )[0] + if ompt_thread_data != ompd_value: + print( + "OMPT-OMPD mismatch: value of ompt_thread_data (%d) does not match that of OMPD data union (%d)!" + % (ompt_thread_data, ompd_value) + ) + + # compare number of threads + if "omp_num_threads" in field_names and "team-size-var" in self.icv_map: + ompt_num_threads = thread_data["omp_num_threads"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.get_current_parallel_handle(), + self.icv_map["team-size-var"][1], + self.icv_map["team-size-var"][0], + ) + if ompt_num_threads != icv_value: + print( + "OMPT-OMPD mismatch: omp_num_threads (%d) does not match OMPD num threads according to ICVs (%d)!" + % (ompt_num_threads, icv_value) + ) + + # compare omp level + if "omp_level" in field_names and "levels-var" in self.icv_map: + ompt_levels = thread_data["omp_level"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.get_current_parallel_handle(), + self.icv_map["levels-var"][1], + self.icv_map["levels-var"][0], + ) + if ompt_levels != icv_value: + print( + "OMPT-OMPD mismatch: omp_level (%d) does not match OMPD levels according to ICVs (%d)!" + % (ompt_levels, icv_value) + ) + + # compare active level + if "omp_active_level" in field_names and "active-levels-var" in self.icv_map: + ompt_active_levels = thread_data["omp_active_level"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.get_current_parallel_handle(), + self.icv_map["active-levels-var"][1], + self.icv_map["active-levels-var"][0], + ) + if ompt_active_levels != icv_value: + print( + "OMPT-OMPD mismatch: active levels (%d) do not match active levels according to ICVs (%d)!" + % (ompt_active_levels, icv_value) + ) + + # compare parallel data + if "ompt_parallel_data" in field_names: + ompt_parallel_data = thread_data["ompt_parallel_data"].dereference()[ + "value" + ] + current_parallel_handle = curr_thread.get_current_parallel_handle() + ompd_value = ompdModule.call_ompd_get_tool_data(4, current_parallel_handle)[ + 0 + ] + if ompt_parallel_data != ompd_value: + print( + "OMPT-OMPD mismatch: value of ompt_parallel_data (%d) does not match that of OMPD data union (%d)!" + % (ompt_parallel_data, ompd_value) + ) + + # compare max threads + if "omp_max_threads" in field_names and "nthreads-var" in self.icv_map: + ompt_max_threads = thread_data["omp_max_threads"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.thread_handle, + self.icv_map["nthreads-var"][1], + self.icv_map["nthreads-var"][0], + ) + if icv_value is None: + icv_string = ompdModule.call_ompd_get_icv_string_from_scope( + curr_thread.thread_handle, + self.icv_map["nthreads-var"][1], + self.icv_map["nthreads-var"][0], + ) + if icv_string is None: + print( + "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (None Object)" + % (ompt_max_threads) + ) + else: + if ompt_max_threads != int(icv_string.split(",")[0]): + print( + "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!" + % (ompt_max_threads, int(icv_string.split(",")[0])) + ) + else: + if ompt_max_threads != icv_value: + print( + "OMPT-OMPD mismatch: omp_max_threads (%d) does not match OMPD thread limit according to ICVs (%d)!" + % (ompt_max_threads, icv_value) + ) + + # compare omp_parallel + # NOTE: omp_parallel = true if active-levels-var > 0 + if "omp_parallel" in field_names: + ompt_parallel = thread_data["omp_parallel"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.get_current_parallel_handle(), + self.icv_map["active-levels-var"][1], + self.icv_map["active-levels-var"][0], + ) + if ( + ompt_parallel == 1 + and icv_value <= 0 + or ompt_parallel == 0 + and icv_value > 0 + ): + print( + "OMPT-OMPD mismatch: ompt_parallel (%d) does not match OMPD parallel according to ICVs (%d)!" + % (ompt_parallel, icv_value) + ) + + # compare omp_final + if "omp_final" in field_names and "final-task-var" in self.icv_map: + ompt_final = thread_data["omp_final"] + current_task_handle = curr_thread.get_current_task_handle() + icv_value = ompdModule.call_ompd_get_icv_from_scope( + current_task_handle, + self.icv_map["final-task-var"][1], + self.icv_map["final-task-var"][0], + ) + if icv_value != ompt_final: + print( + "OMPT-OMPD mismatch: omp_final (%d) does not match OMPD final according to ICVs (%d)!" + % (ompt_final, icv_value) + ) + + # compare omp_dynamic + if "omp_dynamic" in field_names and "dyn-var" in self.icv_map: + ompt_dynamic = thread_data["omp_dynamic"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.thread_handle, + self.icv_map["dyn-var"][1], + self.icv_map["dyn-var"][0], + ) + if icv_value != ompt_dynamic: + print( + "OMPT-OMPD mismatch: omp_dynamic (%d) does not match OMPD dynamic according to ICVs (%d)!" + % (ompt_dynamic, icv_value) + ) + + # compare omp_max_active_levels + if ( + "omp_max_active_levels" in field_names + and "max-active-levels-var" in self.icv_map + ): + ompt_max_active_levels = thread_data["omp_max_active_levels"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.get_current_task_handle(), + self.icv_map["max-active-levels-var"][1], + self.icv_map["max-active-levels-var"][0], + ) + if ompt_max_active_levels != icv_value: + print( + "OMPT-OMPD mismatch: omp_max_active_levels (%d) does not match OMPD max active levels (%d)!" + % (ompt_max_active_levels, icv_value) + ) + # compare omp_kind: TODO: Add the test for monotonic/nonmonotonic modifier - if 'omp_kind' in field_names and 'run-sched-var' in self.icv_map: - ompt_sched_kind = thread_data['omp_kind'] - icv_value = ompdModule.call_ompd_get_icv_string_from_scope(curr_thread.get_current_task_handle(), self.icv_map['run-sched-var'][1], self.icv_map['run-sched-var'][0]) - ompd_sched_kind = icv_value.split(',')[0] - if self.sched_map.get(int(ompt_sched_kind)) != ompd_sched_kind: - print('OMPT-OMPD mismatch: omp_kind kind (%s) does not match OMPD schedule kind according to ICVs (%s)!' % (self.sched_map.get(int(ompt_sched_kind)), ompd_sched_kind)) - - # compare omp_modifier - if 'omp_modifier' in field_names and 'run-sched-var' in self.icv_map: - ompt_sched_mod = thread_data['omp_modifier'] - icv_value = ompdModule.call_ompd_get_icv_string_from_scope(curr_thread.get_current_task_handle(), self.icv_map['run-sched-var'][1], self.icv_map['run-sched-var'][0]) - token = icv_value.split(',')[1] - if token is not None: - ompd_sched_mod = int(token) - else: - ompd_sched_mod = 0 - if ompt_sched_mod != ompd_sched_mod: - print('OMPT-OMPD mismatch: omp_kind modifier does not match OMPD schedule modifier according to ICVs!') - - # compare omp_proc_bind - if 'omp_proc_bind' in field_names and 'bind-var' in self.icv_map: - ompt_proc_bind = thread_data['omp_proc_bind'] - icv_value = ompdModule.call_ompd_get_icv_from_scope(curr_thread.get_current_task_handle(), self.icv_map['bind-var'][1], self.icv_map['bind-var'][0]) - if icv_value is None: - icv_string = ompdModule.call_ompd_get_icv_string_from_scope(curr_thread.get_current_task_handle(), self.icv_map['bind-var'][1], self.icv_map['bind-var'][0]) - if icv_string is None: - print('OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (None Object)' % (ompt_proc_bind)) - else: - if ompt_proc_bind != int(icv_string.split(',')[0]): - print('OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!' % (ompt_proc_bind, int(icv_string.split(',')[0]))) - else: - if ompt_proc_bind != icv_value: - print('OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!' % (ompt_proc_bind, icv_value)) - - # compare enter and exit frames - if 'ompt_frame_list' in field_names: - ompt_task_frame_dict = thread_data['ompt_frame_list'].dereference() - ompt_task_frames = (int(ompt_task_frame_dict['enter_frame'].cast(gdb.lookup_type('long'))), int(ompt_task_frame_dict['exit_frame'].cast(gdb.lookup_type('long')))) - current_task = curr_thread.get_current_task() - ompd_task_frames = current_task.get_task_frame() - if ompt_task_frames != ompd_task_frames: - print('OMPT-OMPD mismatch: ompt_task_frames (%s) do not match OMPD task frames (%s)!' % (ompt_task_frames, ompd_task_frames)) - - # compare task data - if 'ompt_task_data' in field_names: - ompt_task_data = thread_data['ompt_task_data'].dereference()['value'] - current_task_handle = curr_thread.get_current_task_handle() - ompd_value = ompdModule.call_ompd_get_tool_data(6, current_task_handle)[0] - if ompt_task_data != ompd_value: - print('OMPT-OMPD mismatch: value of ompt_task_data (%d) does not match that of OMPD data union (%d)!' % (ompt_task_data, ompd_value)) - - def save_thread_object(self, thread_num, thread_id, addr_space): - """Saves thread object for thread_num inside threads dictionary. - """ - thread_handle = ompdModule.get_thread_handle(thread_id, addr_space) - self.threads[int(thread_num)] = ompd_thread(thread_handle) - - def get_thread(self, thread_num): - """ Get thread object from map. - """ - return self.threads[int(thread_num)] - - def get_curr_thread(self): - """ Get current thread object from map or add new one to map, if missing. - """ - thread_num = int(gdb.selected_thread().num) - if thread_num not in self.threads: - self.add_thread() - return self.threads[thread_num] - - def add_thread(self): - """Add currently selected (*) thread to dictionary threads. - """ - inf_thread = gdb.selected_thread() - try: - self.save_thread_object(inf_thread.num, inf_thread.ptid[1], self.addr_space) - except: - traceback.print_exc() - - def list_threads(self, verbose): - """Prints OpenMP threads only that are being tracking inside the "threads" dictionary. - See handle_stop_event and add_thread. - """ - list_tids = [] - curr_inferior = gdb.selected_inferior() - - for inf_thread in curr_inferior.threads(): - list_tids.append((inf_thread.num, inf_thread.ptid)) - if verbose: - if self.states is None: - self.enumerate_states() - for (thread_num, thread_ptid) in sorted(list_tids): - if thread_num in self.threads: - try: - print('Thread %i (%i) is an OpenMP thread; state: %s' % (thread_num, thread_ptid[1], self.states[self.threads[thread_num].get_state()[0]])) - except: - traceback.print_exc() - else: - print('Thread %i (%i) is no OpenMP thread' % (thread_num, thread_ptid[1])) - - def enumerate_states(self): - """Helper function for list_threads: initializes map of OMPD states for output of - 'ompd threads'. - """ - if self.states is None: - self.states = {} - current = int("0x102", 0) - count = 0 - more = 1 - - while more > 0: - tup = ompdModule.call_ompd_enumerate_states(self.addr_space, current) - (next_state, next_state_name, more) = tup - - self.states[next_state] = next_state_name - current = next_state + if "omp_kind" in field_names and "run-sched-var" in self.icv_map: + ompt_sched_kind = thread_data["omp_kind"] + icv_value = ompdModule.call_ompd_get_icv_string_from_scope( + curr_thread.get_current_task_handle(), + self.icv_map["run-sched-var"][1], + self.icv_map["run-sched-var"][0], + ) + ompd_sched_kind = icv_value.split(",")[0] + if self.sched_map.get(int(ompt_sched_kind)) != ompd_sched_kind: + print( + "OMPT-OMPD mismatch: omp_kind kind (%s) does not match OMPD schedule kind according to ICVs (%s)!" + % (self.sched_map.get(int(ompt_sched_kind)), ompd_sched_kind) + ) + + # compare omp_modifier + if "omp_modifier" in field_names and "run-sched-var" in self.icv_map: + ompt_sched_mod = thread_data["omp_modifier"] + icv_value = ompdModule.call_ompd_get_icv_string_from_scope( + curr_thread.get_current_task_handle(), + self.icv_map["run-sched-var"][1], + self.icv_map["run-sched-var"][0], + ) + token = icv_value.split(",")[1] + if token is not None: + ompd_sched_mod = int(token) + else: + ompd_sched_mod = 0 + if ompt_sched_mod != ompd_sched_mod: + print( + "OMPT-OMPD mismatch: omp_kind modifier does not match OMPD schedule modifier according to ICVs!" + ) + + # compare omp_proc_bind + if "omp_proc_bind" in field_names and "bind-var" in self.icv_map: + ompt_proc_bind = thread_data["omp_proc_bind"] + icv_value = ompdModule.call_ompd_get_icv_from_scope( + curr_thread.get_current_task_handle(), + self.icv_map["bind-var"][1], + self.icv_map["bind-var"][0], + ) + if icv_value is None: + icv_string = ompdModule.call_ompd_get_icv_string_from_scope( + curr_thread.get_current_task_handle(), + self.icv_map["bind-var"][1], + self.icv_map["bind-var"][0], + ) + if icv_string is None: + print( + "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (None Object)" + % (ompt_proc_bind) + ) + else: + if ompt_proc_bind != int(icv_string.split(",")[0]): + print( + "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!" + % (ompt_proc_bind, int(icv_string.split(",")[0])) + ) + else: + if ompt_proc_bind != icv_value: + print( + "OMPT-OMPD mismatch: omp_proc_bind (%d) does not match OMPD proc bind according to ICVs (%d)!" + % (ompt_proc_bind, icv_value) + ) + + # compare enter and exit frames + if "ompt_frame_list" in field_names: + ompt_task_frame_dict = thread_data["ompt_frame_list"].dereference() + ompt_task_frames = ( + int(ompt_task_frame_dict["enter_frame"].cast(gdb.lookup_type("long"))), + int(ompt_task_frame_dict["exit_frame"].cast(gdb.lookup_type("long"))), + ) + current_task = curr_thread.get_current_task() + ompd_task_frames = current_task.get_task_frame() + if ompt_task_frames != ompd_task_frames: + print( + "OMPT-OMPD mismatch: ompt_task_frames (%s) do not match OMPD task frames (%s)!" + % (ompt_task_frames, ompd_task_frames) + ) + + # compare task data + if "ompt_task_data" in field_names: + ompt_task_data = thread_data["ompt_task_data"].dereference()["value"] + current_task_handle = curr_thread.get_current_task_handle() + ompd_value = ompdModule.call_ompd_get_tool_data(6, current_task_handle)[0] + if ompt_task_data != ompd_value: + print( + "OMPT-OMPD mismatch: value of ompt_task_data (%d) does not match that of OMPD data union (%d)!" + % (ompt_task_data, ompd_value) + ) + + def save_thread_object(self, thread_num, thread_id, addr_space): + """Saves thread object for thread_num inside threads dictionary.""" + thread_handle = ompdModule.get_thread_handle(thread_id, addr_space) + self.threads[int(thread_num)] = ompd_thread(thread_handle) + + def get_thread(self, thread_num): + """Get thread object from map.""" + return self.threads[int(thread_num)] + + def get_curr_thread(self): + """Get current thread object from map or add new one to map, if missing.""" + thread_num = int(gdb.selected_thread().num) + if thread_num not in self.threads: + self.add_thread() + return self.threads[thread_num] + + def add_thread(self): + """Add currently selected (*) thread to dictionary threads.""" + inf_thread = gdb.selected_thread() + try: + self.save_thread_object(inf_thread.num, inf_thread.ptid[1], self.addr_space) + except: + traceback.print_exc() + + def list_threads(self, verbose): + """Prints OpenMP threads only that are being tracking inside the "threads" dictionary. + See handle_stop_event and add_thread. + """ + list_tids = [] + curr_inferior = gdb.selected_inferior() + + for inf_thread in curr_inferior.threads(): + list_tids.append((inf_thread.num, inf_thread.ptid)) + if verbose: + if self.states is None: + self.enumerate_states() + for (thread_num, thread_ptid) in sorted(list_tids): + if thread_num in self.threads: + try: + print( + "Thread %i (%i) is an OpenMP thread; state: %s" + % ( + thread_num, + thread_ptid[1], + self.states[self.threads[thread_num].get_state()[0]], + ) + ) + except: + traceback.print_exc() + else: + print( + "Thread %i (%i) is no OpenMP thread" + % (thread_num, thread_ptid[1]) + ) + + def enumerate_states(self): + """Helper function for list_threads: initializes map of OMPD states for output of + 'ompd threads'. + """ + if self.states is None: + self.states = {} + current = int("0x102", 0) + count = 0 + more = 1 + + while more > 0: + tup = ompdModule.call_ompd_enumerate_states(self.addr_space, current) + (next_state, next_state_name, more) = tup + + self.states[next_state] = next_state_name + current = next_state diff --git a/openmp/libompd/gdb-plugin/ompd/ompd_callbacks.py b/openmp/libompd/gdb-plugin/ompd/ompd_callbacks.py index bb520e5..ada09d7 100644 --- a/openmp/libompd/gdb-plugin/ompd/ompd_callbacks.py +++ b/openmp/libompd/gdb-plugin/ompd/ompd_callbacks.py @@ -9,88 +9,104 @@ import sys """ Have the debugger print a string. """ + + def _print(*args): - # args is a tuple with just one string element - print_string = args[0] - gdb.execute('printf "%s\n"' % args[0]) + # args is a tuple with just one string element + print_string = args[0] + gdb.execute('printf "%s\n"' % args[0]) + """ Look up the address of a global symbol in the target. """ + + def _sym_addr(*args): - # args is a tuple consisting of thread_id and symbol_name - thread_id = args[0] - symbol_name = args[1] - if(thread_id >= 0): - gdb.execute('thread %d\n' % thread_id, to_string=True) - return int(gdb.parse_and_eval("&"+symbol_name)) + # args is a tuple consisting of thread_id and symbol_name + thread_id = args[0] + symbol_name = args[1] + if thread_id >= 0: + gdb.execute("thread %d\n" % thread_id, to_string=True) + return int(gdb.parse_and_eval("&" + symbol_name)) + """ Read string from the target and copy it into the provided buffer. """ + + def _read_string(*args): - # args is a tuple with just the source address - addr = args[0] - try: - buf = gdb.parse_and_eval('(unsigned char*)%li' % addr).string() - except: - traceback.print_exc() - return buf + # args is a tuple with just the source address + addr = args[0] + try: + buf = gdb.parse_and_eval("(unsigned char*)%li" % addr).string() + except: + traceback.print_exc() + return buf + """ Read memory from the target and copy it into the provided buffer. """ + + def _read(*args): - # args is a tuple consisting of address and number of bytes to be read - addr = args[0] - nbytes = args[1] -# print("_read(%i,%i)"%(addr, nbytes)) - ret_buf = bytearray() -# try: - buf = gdb.parse_and_eval('(unsigned char*)%li' % addr) - for i in range(nbytes): - ret_buf.append(int(buf[i])) -# except: -# traceback.print_exc() - return ret_buf + # args is a tuple consisting of address and number of bytes to be read + addr = args[0] + nbytes = args[1] + # print("_read(%i,%i)"%(addr, nbytes)) + ret_buf = bytearray() + # try: + buf = gdb.parse_and_eval("(unsigned char*)%li" % addr) + for i in range(nbytes): + ret_buf.append(int(buf[i])) + # except: + # traceback.print_exc() + return ret_buf """ Get thread-specific context. Return -1 if no match is found. """ + + def _thread_context(*args): - # args is a tuple consisting of thread_id and the thread kind - thread_id = args[1] - pthread = False - lwp = False - if args[0] == 0: - pthread = True - else: - lwp = True - info = gdb.execute('info threads', to_string=True).splitlines() - - for line in info: - if pthread: - m = re.search(r'(0x[a-fA-F0-9]+)', line) - elif lwp: - m = re.search(r'\([^)]*?(\d+)[^)]*?\)', line) - if m == None: - continue - pid = int(m.group(1),0) - if pid == thread_id: - return int(line[2:6],0) - return -1 + # args is a tuple consisting of thread_id and the thread kind + thread_id = args[1] + pthread = False + lwp = False + if args[0] == 0: + pthread = True + else: + lwp = True + info = gdb.execute("info threads", to_string=True).splitlines() + + for line in info: + if pthread: + m = re.search(r"(0x[a-fA-F0-9]+)", line) + elif lwp: + m = re.search(r"\([^)]*?(\d+)[^)]*?\)", line) + if m == None: + continue + pid = int(m.group(1), 0) + if pid == thread_id: + return int(line[2:6], 0) + return -1 + """ Test info threads / list threads / how to split output to get thread id and its size. """ + + def _test_threads(*args): - info = gdb.execute('info threads', to_string=True).splitlines() - for line in info[1:]: - content = line.split() - thread_id = None - # fetch pointer to id - if(content[0].startswith('*')): - thread_id = (content[3]) - else: - thread_id = (content[2]) - sizeof_tid = sys.getsizeof(thread_id) - print(sizeof_tid) - print(info) + info = gdb.execute("info threads", to_string=True).splitlines() + for line in info[1:]: + content = line.split() + thread_id = None + # fetch pointer to id + if content[0].startswith("*"): + thread_id = content[3] + else: + thread_id = content[2] + sizeof_tid = sys.getsizeof(thread_id) + print(sizeof_tid) + print(info) diff --git a/openmp/libompd/gdb-plugin/ompd/ompd_handles.py b/openmp/libompd/gdb-plugin/ompd/ompd_handles.py index 1aaccb1..1929a92 100644 --- a/openmp/libompd/gdb-plugin/ompd/ompd_handles.py +++ b/openmp/libompd/gdb-plugin/ompd/ompd_handles.py @@ -1,178 +1,200 @@ import ompdModule import imp + class ompd_parallel(object): - - def __init__(self, parallel_handle): - """ Initializes an ompd_parallel object with the pointer - to a handle of a parallel region.""" - self.parallel_handle = parallel_handle - self.threads = {} - self.itasks = {} - self.enclosing_parallel_handle = None - self.enclosing_parallel = False - self.task_handle = None - - def get_thread_in_parallel(self, thread_num): - """Obtains thread handles for the threads associated with the - parallel region specified by parallel_handle.""" - if not thread_num in self.threads: - thread_handle = ompdModule.call_ompd_get_thread_in_parallel(self.parallel_handle, thread_num) - self.threads[thread_num] = ompd_thread(thread_handle) - return self.threads[thread_num] - - def get_enclosing_parallel_handle(self): - """Obtains a parallel handle for the parallel region enclosing - the parallel region specified by parallel_handle.""" - if not self.enclosing_parallel_handle: - self.enclosing_parallel_handle = ompdModule.call_ompd_get_enclosing_parallel_handle(self.parallel_handle) - return self.enclosing_parallel_handle - - def get_enclosing_parallel(self): - if not self.enclosing_parallel: - self.enclosing_parallel = ompd_parallel(self.get_enclosing_parallel_handle()) - return self.enclosing_parallel - - def get_task_in_parallel(self, thread_num): - """Obtains handles for the implicit tasks associated with the - parallel region specified by parallel_handle.""" - if not thread_num in self.itasks: - task_handle = ompdModule.call_ompd_get_task_in_parallel(self.parallel_handle, thread_num) - self.itasks[thread_num] = ompd_task(task_handle) - return self.itasks[thread_num] - - def __del__(self): - """Releases the parallel handle.""" - pass # let capsule destructors do the job + def __init__(self, parallel_handle): + """Initializes an ompd_parallel object with the pointer + to a handle of a parallel region.""" + self.parallel_handle = parallel_handle + self.threads = {} + self.itasks = {} + self.enclosing_parallel_handle = None + self.enclosing_parallel = False + self.task_handle = None + + def get_thread_in_parallel(self, thread_num): + """Obtains thread handles for the threads associated with the + parallel region specified by parallel_handle.""" + if not thread_num in self.threads: + thread_handle = ompdModule.call_ompd_get_thread_in_parallel( + self.parallel_handle, thread_num + ) + self.threads[thread_num] = ompd_thread(thread_handle) + return self.threads[thread_num] + + def get_enclosing_parallel_handle(self): + """Obtains a parallel handle for the parallel region enclosing + the parallel region specified by parallel_handle.""" + if not self.enclosing_parallel_handle: + self.enclosing_parallel_handle = ( + ompdModule.call_ompd_get_enclosing_parallel_handle(self.parallel_handle) + ) + return self.enclosing_parallel_handle + + def get_enclosing_parallel(self): + if not self.enclosing_parallel: + self.enclosing_parallel = ompd_parallel( + self.get_enclosing_parallel_handle() + ) + return self.enclosing_parallel + + def get_task_in_parallel(self, thread_num): + """Obtains handles for the implicit tasks associated with the + parallel region specified by parallel_handle.""" + if not thread_num in self.itasks: + task_handle = ompdModule.call_ompd_get_task_in_parallel( + self.parallel_handle, thread_num + ) + self.itasks[thread_num] = ompd_task(task_handle) + return self.itasks[thread_num] + + def __del__(self): + """Releases the parallel handle.""" + pass # let capsule destructors do the job + class ompd_task(object): - - def __init__(self, task_handle): - """Initializes a new ompd_task_handle object and sets the attribute - to the task handle specified.""" - self.task_handle = task_handle - self.task_parallel_handle = False - self.generating_task_handle = False - self.scheduling_task_handle = False - self.task_parallel = False - self.generating_task = False - self.scheduling_task = False - self.task_frames = None - self.task_frame_flags = None - - def get_task_parallel_handle(self): - """Obtains a task parallel handle for the parallel region enclosing - the task region specified.""" - if not self.task_parallel_handle: - self.task_parallel_handle = ompdModule.call_ompd_get_task_parallel_handle(self.task_handle) - return self.task_parallel_handle - - def get_task_parallel(self): - if not self.task_parallel: - self.task_parallel = ompd_parallel(self.get_task_parallel_handle()) - return self.task_parallel - - def get_generating_task_handle(self): - """Obtains the task handle for the task that created the task specified - by the task handle.""" - if not self.generating_task_handle: - self.generating_task_handle = ompdModule.call_ompd_get_generating_task_handle(self.task_handle) - return self.generating_task_handle - - def get_generating_task(self): - if not self.generating_task: - self.generating_task = ompd_task(ompdModule.call_ompd_get_generating_task_handle(self.task_handle)) - return self.generating_task - - def get_scheduling_task_handle(self): - """Obtains the task handle for the task that scheduled the task specified.""" - if not self.scheduling_task_handle: - self.scheduling_task_handle = ompdModule.call_ompd_get_scheduling_task_handle(self.task_handle) - return self.scheduling_task_handle - - def get_scheduling_task(self): - """Returns ompd_task object for the task that scheduled the current task.""" - if not self.scheduling_task: - self.scheduling_task = ompd_task(self.get_scheduling_task_handle()) - return self.scheduling_task - - def get_task_function(self): - """Returns long with address of function entry point.""" - return ompdModule.call_ompd_get_task_function(self.task_handle) - - def get_task_frame_with_flags(self): - """Returns enter frame address and flag, exit frame address and flag for current task handle.""" - if self.task_frames is None or self.task_frame_flags is None: - ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle) - if isinstance(ret_value, tuple): - self.task_frames = (ret_value[0], ret_value[2]) - self.task_frame_flags = (ret_value[1], ret_value[3]) - else: - return ret_value - return (self.task_frames[0], self.task_frame_flags[0], self.task_frames[1], self.task_frame_flags[1]) - - def get_task_frame(self): - """Returns enter and exit frame address for current task handle.""" - if self.task_frames is None: - ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle) - if isinstance(ret_value, tuple): - self.task_frames = (ret_value[0], ret_value[2]) - else: - return ret_value - return self.task_frames - - def __del__(self): - """Releases the task handle.""" - pass # let capsule destructors do the job + def __init__(self, task_handle): + """Initializes a new ompd_task_handle object and sets the attribute + to the task handle specified.""" + self.task_handle = task_handle + self.task_parallel_handle = False + self.generating_task_handle = False + self.scheduling_task_handle = False + self.task_parallel = False + self.generating_task = False + self.scheduling_task = False + self.task_frames = None + self.task_frame_flags = None + + def get_task_parallel_handle(self): + """Obtains a task parallel handle for the parallel region enclosing + the task region specified.""" + if not self.task_parallel_handle: + self.task_parallel_handle = ompdModule.call_ompd_get_task_parallel_handle( + self.task_handle + ) + return self.task_parallel_handle + + def get_task_parallel(self): + if not self.task_parallel: + self.task_parallel = ompd_parallel(self.get_task_parallel_handle()) + return self.task_parallel + + def get_generating_task_handle(self): + """Obtains the task handle for the task that created the task specified + by the task handle.""" + if not self.generating_task_handle: + self.generating_task_handle = ( + ompdModule.call_ompd_get_generating_task_handle(self.task_handle) + ) + return self.generating_task_handle + + def get_generating_task(self): + if not self.generating_task: + self.generating_task = ompd_task( + ompdModule.call_ompd_get_generating_task_handle(self.task_handle) + ) + return self.generating_task + + def get_scheduling_task_handle(self): + """Obtains the task handle for the task that scheduled the task specified.""" + if not self.scheduling_task_handle: + self.scheduling_task_handle = ( + ompdModule.call_ompd_get_scheduling_task_handle(self.task_handle) + ) + return self.scheduling_task_handle + + def get_scheduling_task(self): + """Returns ompd_task object for the task that scheduled the current task.""" + if not self.scheduling_task: + self.scheduling_task = ompd_task(self.get_scheduling_task_handle()) + return self.scheduling_task + + def get_task_function(self): + """Returns long with address of function entry point.""" + return ompdModule.call_ompd_get_task_function(self.task_handle) + + def get_task_frame_with_flags(self): + """Returns enter frame address and flag, exit frame address and flag for current task handle.""" + if self.task_frames is None or self.task_frame_flags is None: + ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle) + if isinstance(ret_value, tuple): + self.task_frames = (ret_value[0], ret_value[2]) + self.task_frame_flags = (ret_value[1], ret_value[3]) + else: + return ret_value + return ( + self.task_frames[0], + self.task_frame_flags[0], + self.task_frames[1], + self.task_frame_flags[1], + ) + + def get_task_frame(self): + """Returns enter and exit frame address for current task handle.""" + if self.task_frames is None: + ret_value = ompdModule.call_ompd_get_task_frame(self.task_handle) + if isinstance(ret_value, tuple): + self.task_frames = (ret_value[0], ret_value[2]) + else: + return ret_value + return self.task_frames + + def __del__(self): + """Releases the task handle.""" + pass # let capsule destructors do the job class ompd_thread(object): - - def __init__(self, thread_handle): - """Initializes an ompd_thread with the data received from - GDB.""" - self.thread_handle = thread_handle - self.parallel_handle = None - self.task_handle = None - self.current_task = False - self.current_parallel = False - self.thread_id = False - - def get_current_parallel_handle(self): - """Obtains the parallel handle for the parallel region associated with - the given thread handle.""" - #TODO: invalidate thread objects based on `gdb.event.cont`. This should invalidate all internal state. - self.parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle(self.thread_handle) - return self.parallel_handle - - def get_current_parallel(self): - """Returns parallel object for parallel handle of the parallel region - associated with the current thread handle.""" - if not self.current_parallel: - self.current_parallel = ompd_parallel(self.get_current_parallel_handle()) - return self.current_parallel - - def get_current_task_handle(self): - """Obtains the task handle for the current task region of the - given thread.""" - return ompdModule.call_ompd_get_curr_task_handle(self.thread_handle) - - def get_thread_id(self): - """Obtains the ID for the given thread.""" - if not self.thread_id: - self.thread_id = ompdModule.call_ompd_get_thread_id(self.thread_handle) - return self.thread_id - - def get_current_task(self): - """Returns task object for task handle of the current task region.""" - return ompd_task(self.get_current_task_handle()) - - def get_state(self): - """Returns tuple with OMPD state (long) and wait_id, in case the thread is in a - waiting state. Helper function for 'ompd threads' command.""" - (state, wait_id) = ompdModule.call_ompd_get_state(self.thread_handle) - return (state, wait_id) - - def __del__(self): - """Releases the given thread handle.""" - pass # let capsule destructors do the job + def __init__(self, thread_handle): + """Initializes an ompd_thread with the data received from + GDB.""" + self.thread_handle = thread_handle + self.parallel_handle = None + self.task_handle = None + self.current_task = False + self.current_parallel = False + self.thread_id = False + + def get_current_parallel_handle(self): + """Obtains the parallel handle for the parallel region associated with + the given thread handle.""" + # TODO: invalidate thread objects based on `gdb.event.cont`. This should invalidate all internal state. + self.parallel_handle = ompdModule.call_ompd_get_curr_parallel_handle( + self.thread_handle + ) + return self.parallel_handle + + def get_current_parallel(self): + """Returns parallel object for parallel handle of the parallel region + associated with the current thread handle.""" + if not self.current_parallel: + self.current_parallel = ompd_parallel(self.get_current_parallel_handle()) + return self.current_parallel + + def get_current_task_handle(self): + """Obtains the task handle for the current task region of the + given thread.""" + return ompdModule.call_ompd_get_curr_task_handle(self.thread_handle) + + def get_thread_id(self): + """Obtains the ID for the given thread.""" + if not self.thread_id: + self.thread_id = ompdModule.call_ompd_get_thread_id(self.thread_handle) + return self.thread_id + + def get_current_task(self): + """Returns task object for task handle of the current task region.""" + return ompd_task(self.get_current_task_handle()) + + def get_state(self): + """Returns tuple with OMPD state (long) and wait_id, in case the thread is in a + waiting state. Helper function for 'ompd threads' command.""" + (state, wait_id) = ompdModule.call_ompd_get_state(self.thread_handle) + return (state, wait_id) + + def __del__(self): + """Releases the given thread handle.""" + pass # let capsule destructors do the job |