static int generate_internal(MarkovData* data, int max_words, int (*output_func)(const char*, void*), void* output_data) { if (! data->initialized) return 1; if (max_words == 0) max_words = data->output_words; const char* prefix[data->prefix_len]; prepopulate_prefix(data, prefix); srand( (unsigned int) time(NULL)); while(max_words-- > 0) { StateNode* state = lookup_state(data, prefix); //possibly should check for null, but should always exist const char* word = NULL; int count = 0; for(SuffixNode* s = state->list; s != NULL; s = s->next) { if (rand() % ++count == 0) { word = s->suffix; } } if (strcmp(word, data->sentinel_word) == 0) { break; } if (output_func(word, output_data)) return 1; rotate_prefix(data, prefix, word); } return 0; }
static void real_handle_cont( pid_t pid, pid_state *state ) { pid_t child=(pid_t)state->context_state[1]; pid_state *child_state=lookup_state( child ); __ptrace_request req=(__ptrace_request)state->context_state[0]; if( req==PTRACE_CONT ) { child_state->trace_mode|=TRACE_CONT; dlog("ptrace: %d PTRACE_CONT(" PID_F ")\n", pid, child ); } else if( req==PTRACE_SYSCALL ) { child_state->trace_mode|=TRACE_SYSCALL; dlog("ptrace: %d PTRACE_SYSCALL(" PID_F ")\n", pid, child ); } else if( req==PTRACE_DETACH ) { child_state->trace_mode&=TRACE_MASK2; } else { // Wrong mode for calling this function! } long rc=0; if( (child_state->trace_mode&TRACE_MASK2)==TRACE_STOPPED1 ) { dlog("handle_cont_syscall: " PID_F " process " PID_F " was in pre-syscall hook\n", pid, child ); // Need to restart the syscall int status=child_state->context_state[1]; PTLIB_WAIT_RET wait_state=(PTLIB_WAIT_RET)child_state->context_state[0]; long ret=ptlib_get_syscall( child ); int sig=process_sigchld( child, wait_state, status, ret ); // If our processing requested no special handling, use the signal requested by the debugger if( sig==0 ) { sig=(int)state->context_state[3]; } if( sig>=0 ) { rc=ptlib_continue(PTRACE_SYSCALL, child, sig); } } else if( (child_state->trace_mode&TRACE_MASK2)==TRACE_STOPPED2 ) { dlog("handle_cont_syscall: " PID_F " process " PID_F " was in post-syscall hook\n", pid, child ); child_state->trace_mode&=TRACE_MASK1; rc=ptlib_continue( PTRACE_SYSCALL, child, (int)state->context_state[3] ); } else { // Our child was not stopped (at least, by us) // This is an internal inconsistency dlog("handle_cont_syscall: " PID_F " process " PID_F " was started with no specific state (%x)\n", pid, child, child_state->trace_mode ); dlog(NULL); rc=-1; } if( rc!=-1 ) { dlog("ptrace: %d request successful\n", pid ); ptlib_set_retval( pid, rc ); } else { ptlib_set_error( pid, state->orig_sc, errno ); dlog("ptrace: %d request failed: %s\n", pid, strerror(errno) ); } }
static bool begin_trace( pid_t debugger, pid_t child ) { pid_state *child_state=lookup_state( child ); pid_state *parent_state=lookup_state( debugger ); if( child_state==NULL || parent_state==NULL || child_state->debugger!=0 ) { dlog("begin_trace: %d Failed to start trace for " PID_F ": child_state=%p, parent_state=%p", debugger, child, child_state, parent_state ); if( child_state!=NULL ) { dlog("child_state debugger=" PID_F, child_state->debugger); } dlog("\n"); errno=EPERM; return false; } child_state->debugger=debugger; child_state->trace_mode=PTRACE_CONT; parent_state->num_debugees++; return true; }
static bool handle_detach( pid_t pid, pid_state *state ) { if( verify_permission( pid, state ) ) { dlog("ptrace: %d PTRACE_DETACH(" PID_F ")\n", pid, (pid_t)state->context_state[1]); pid_state *child_state=lookup_state((pid_t)state->context_state[1]); child_state->debugger=0; state->num_debugees--; child_state->trace_mode&=TRACE_MASK2; // Call the cont handler to make sure the debuggee is runing again real_handle_cont( pid, state ); return true; } else { ptlib_set_error( pid, state->orig_sc, errno ); return false; } }
static void add_suffix(MarkovData* data, const char** prefix, const char* word) { StateNode* state_node = lookup_state(data, prefix); if (state_node == NULL) { state_node = malloc(sizeof(StateNode)); state_node->prefix = malloc(sizeof(char*) * data->prefix_len); for(int i = 0; i < data->prefix_len; i++) { state_node->prefix[i] = prefix[i]; } state_node->list = NULL; int h = hash_prefix(data, prefix); state_node->next = data->statetab[h]; data->statetab[h] = state_node; } SuffixNode* suffix_node = malloc(sizeof(SuffixNode)); suffix_node->suffix = word; suffix_node->next = state_node->list; state_node->list = suffix_node; }
// Retruns true of the specified pid has permission to perform a ptrace operation static bool verify_permission( pid_t pid, pid_state *state ) { pid_t traced=(pid_t)state->context_state[1]; // First, find out whether the pid we work on even exists pid_state *child_state=lookup_state( traced ); if( child_state==NULL || child_state->debugger!=pid ) { dlog("ptrace verify_permission: %d failed permission - not the debugger for " PID_F "\n", pid, traced); errno=ESRCH; return false; } if( child_state->trace_mode!=TRACE_STOPPED1 && child_state->trace_mode!=TRACE_STOPPED2 ) { dlog("ptrace verify_permission: %d failed permission - " PID_F " is not stopped\n", pid, traced); errno=ESRCH; return false; } return true; }
static inline void instance__inspect_new_state( fcs_dbm_solver_instance_t *const instance, fcs_cache_key_t *const state) { instance->count_num_processed++; if (fcs_pdfs_cache_does_key_exist(&(instance->cache), &(state->s))) { instance->stack_depth--; return; } const fcs_dbm_variant_type_t local_variant = instance->local_variant; const int depth = (instance->stack_depth); const int max_depth = instance->max_stack_depth; if (depth == max_depth) { instance->stack = SREALLOC(instance->stack, ++(instance->max_stack_depth)); pseduo_dfs_stack_item_t *const stack_item = instance->stack + max_depth; stack_item->next_states = NULL; stack_item->max_count_next_states = 0; } pseduo_dfs_stack_item_t *const stack_item = instance->stack + depth; stack_item->curr_state = state; fcs_derived_state_t *derived_list = NULL, *derived_iter = NULL; if (instance_solver_thread_calc_derived_states(instance->local_variant, state, NULL, &derived_list, &(instance->derived_list_recycle_bin), &(instance->derived_list_allocator), TRUE)) { instance->should_terminate = SOLUTION_FOUND_TERMINATE; instance->solution_was_found = TRUE; return; } stack_item->count_next_states = 0; stack_item->next_state_idx = 0; fcs_kv_state_t kv; /* Now recycle the derived_list */ while (derived_list) { kv.key = &(derived_list->state.s); kv.val = &(derived_list->state.info); fc_solve_canonize_state(kv.key, FREECELLS_NUM, STACKS_NUM); if (!lookup_state( &(instance->store), &(instance->cache), &(derived_list->state))) { int i = (stack_item->count_next_states)++; if (i >= stack_item->max_count_next_states) { stack_item->next_states = SREALLOC(stack_item->next_states, ++(stack_item->max_count_next_states)); } stack_item->next_states[i] = derived_list->state; insert_state(&(instance->store), &(stack_item->next_states[i])); } #define derived_list_next derived_iter derived_list_next = derived_list->next; derived_list->next = instance->derived_list_recycle_bin; instance->derived_list_recycle_bin = derived_list; derived_list = derived_list_next; #undef derived_list_next } return; }