int proc_is_lingering(apr_uint32_t mod_index) { apr_hash_index_t *hi; for (hi = apr_hash_first(0, processes); hi; hi = apr_hash_next(hi)) { int ebp; process_t *self; //call it self, for cstack to work :-) apr_hash_this(hi, 0, 0, (void **)&self); if (self->mod_index == mod_index) return 1; ebp = self->ebp; while (1) { int return_mod_index = int_value2(cstack(ebp-3)); if (return_mod_index == MOD_INDEX_NONE) break; if (return_mod_index == mod_index) return 1; ebp = int_value2(cstack(ebp-1)); } } return 0; }
term_t proc_trace_stack(process_t *self) { term_t r = nil; term_t cons = nil; int ebp = self->ebp; term_t mod, thrice, pair; int saved_ebp, i; term_t avs = nil; //args+vars term_t cons1 = nil; // arity of the current function is unknown // however, it is known that the arity is less // or equal to saved_ebp - cur_ebp - 3 saved_ebp = int_value2(cstack(ebp-1)); for (i = ebp-4; i >= saved_ebp; i--) { term_t av = cstack(i); lst_add(avs, cons1, av, self->gc_cur); } mod = code_base_mod_name(self->base, self->mod_index); thrice = make_tuple3(mod, intnum(self->ip - self->code), avs, self->gc_cur); lst_add(r, cons, thrice, self->gc_cur); while (1) { int ebp1 = int_value2(cstack(ebp-1)); int offset = int_value2(cstack(ebp-2)); int mod_index = int_value2(cstack(ebp-3)); term_t cons = nil; if (mod_index == MOD_INDEX_NONE) break; mod = code_base_mod_name(self->base, mod_index); pair = make_tuple2(mod, intnum(offset), self->gc_cur); lst_add(r, cons, pair, self->gc_cur); ebp = ebp1; } self->stack_trace = r; return self->stack_trace; }
/** * This function performs a depth-first search (for a compartment) in the tree * with its root at 'base'. Returns (Id of) a compartment if found, else a * blank Id. */ Id HSolve::deepSearchForCompartment( Id base ) { /* * 'cstack' is a stack-of-stacks used to perform the depth-first search. * The 0th entry in 'cstack' is a stack containing simply the base. * The i-th entry in 'cstack' contains children of the node at the top * of the stack at position ( i - 1 ). * Hence, at any time, the top of the i-th stack is the i-th node on * the ancestral path from the 'base' node to the 'current' node * (more below) which is being examined. Also, the remaining nodes in * the i-th stack are the siblings of this ancestor. * * 'current' is the node at the top of the top of 'cstack'. If this node is * a Compartment, then the search is completed, returning 'current'. * Otherwise, the children of 'current' are pushed onto 'cstack' for a * deeper search. If the deeper search yields nothing, then this * 'current' node is discarded. When an entire stack of siblings is * exhausted in this way, then this empty stack is discarded, and * the search moves 1 level up. * * 'result' is a blank Id (moose root element) if the search failed. * Otherwise, it is a compartment that was found under 'base'. */ vector< vector< Id > > cstack( 1, vector< Id >( 1, base ) ); Id current; Id result; while ( !cstack.empty() ) if ( cstack.back().empty() ) { cstack.pop_back(); if ( !cstack.empty() ) cstack.back().pop_back(); } else { current = cstack.back().back(); // if ( current()->cinfo() == moose::Compartment::initCinfo() ) // Compartment is base class for SymCompartment. if ( current.element()->cinfo()->isA( "Compartment" ) ) { result = current; break; } cstack.push_back( children( current ) ); } return result; }
term_t proc_trace_locals(process_t *self) { term_t r = nil; term_t cons = nil; int i; for (i = self->ebp; i < self->cstack->nelts; i++) { term_t local = cstack(i); lst_add(r, cons, local, self->gc_cur); } self->locals_trace = r; return self->locals_trace; }