def set_thread_log_file(self, log_dir): if self.ql.log_split and log_dir != None: _logger = self.ql.log_file_fd self.log_file_fd = ql_setup_logging_file(self.ql.output, log_dir, _logger)
def __init__(self, ql, thread_management = None, start_address = 0, context = None, total_time = 0, set_child_tid_addr = None): super(QlLinuxThread, self).__init__(ql) self.thread_id = QlLinuxThread.LINUX_THREAD_ID QlLinuxThread.LINUX_THREAD_ID += 1 self.total_time = total_time self.runing_time = 0 self.context = context self.ql = ql self.until_addr = ql.until_addr self.start_address = start_address self.status = THREAD_STATUS_RUNNING self.stop_event = THREAD_EVENT_INIT_VAL self.stop_return_val = None self.return_val = 0 self.blocking_condition_fuc = None self.blocking_condition_arg = None self.thread_management = None self.current_path = ql.current_path self.log_file_fd = None _logger = ql_setup_logger(str(self.thread_id)) if ql.log_split else ql_setup_logger() _logger = ql_setup_logging_stream(self.ql, _logger) if ql.log_dir and ql.log_file != None: if ql.log_split: _logger = ql_setup_logging_file(ql.output, '%s_%s' % (ql.log_file, self.thread_id), _logger) else: _logger = ql_setup_logging_file(ql.output, ql.log_file, _logger) self.log_file_fd = _logger # For each thread, the kernel maintains two attributes (addresses) # called set_child_tid and clear_child_tid. These two attributes # contain the value NULL by default. # set_child_tid # If a thread is started using clone(2) with the # CLONE_CHILD_SETTID flag, set_child_tid is set to the value # passed in the ctid argument of that system call. # When set_child_tid is set, the very first thing the new thread # does is to write its thread ID at this address. # clear_child_tid # If a thread is started using clone(2) with the # CLONE_CHILD_CLEARTID flag, clear_child_tid is set to the value # passed in the ctid argument of that system call. # The system call set_tid_address() sets the clear_child_tid value for # the calling thread to tidptr. # When a thread whose clear_child_tid is not NULL terminates, then, if # the thread is sharing memory with other threads, then 0 is written at # the address specified in clear_child_tid and the kernel performs the # following operation: # futex(clear_child_tid, FUTEX_WAKE, 1, NULL, NULL, 0); # The effect of this operation is to wake a single thread that is # performing a futex wait on the memory location. Errors from the # futex wake operation are ignored. self.set_child_tid_address = set_child_tid_addr self.clear_child_tid_address = None self.robust_list_head_ptr = None self.robust_list_head_len = None if self.set_child_tid_address != None: self.ql.mem.write(self.set_child_tid_address, ql.pack32(self.thread_id))