ir_visitor_status ir_explog_to_explog2_visitor::visit_leave(ir_expression *ir) { if (ir->operation == ir_unop_exp) { void *mem_ctx = talloc_parent(ir); ir_constant *log2_e = new(mem_ctx) ir_constant(log2f(M_E)); ir->operation = ir_unop_exp2; ir->operands[0] = new(mem_ctx) ir_expression(ir_binop_mul, ir->operands[0]->type, ir->operands[0], log2_e); this->progress = true; } if (ir->operation == ir_unop_log) { void *mem_ctx = talloc_parent(ir); ir->operation = ir_binop_mul; ir->operands[0] = new(mem_ctx) ir_expression(ir_unop_log2, ir->operands[0]->type, ir->operands[0], NULL); ir->operands[1] = new(mem_ctx) ir_constant(1.0f / log2f(M_E)); this->progress = true; } return visit_continue; }
/** Generate a talloc memory report for a context and print to stderr/stdout * * @param ctx to generate a report for, may be NULL in which case the root context is used. */ int fr_log_talloc_report(TALLOC_CTX *ctx) { #define TALLOC_REPORT_MAX_DEPTH 20 FILE *log; int fd; fd = dup(fr_fault_log_fd); if (fd < 0) { fr_strerror_printf("Couldn't write memory report, failed to dup log fd: %s", fr_syserror(errno)); return -1; } log = fdopen(fd, "w"); if (!log) { close(fd); fr_strerror_printf("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno)); return -1; } if (!ctx) { fprintf(log, "Current state of talloced memory:\n"); talloc_report_full(talloc_null_ctx, log); } else { int i; fprintf(log, "Talloc chunk lineage:\n"); fprintf(log, "%p (%s)", ctx, talloc_get_name(ctx)); i = 0; while ((i < TALLOC_REPORT_MAX_DEPTH) && (ctx = talloc_parent(ctx))) { fprintf(log, " < %p (%s)", ctx, talloc_get_name(ctx)); i++; } fprintf(log, "\n"); i = 0; do { fprintf(log, "Talloc context level %i:\n", i++); talloc_report_full(ctx, log); } while ((ctx = talloc_parent(ctx)) && (i < TALLOC_REPORT_MAX_DEPTH) && (talloc_parent(ctx) != talloc_autofree_ctx) && /* Stop before we hit the autofree ctx */ (talloc_parent(ctx) != talloc_null_ctx)); /* Stop before we hit NULL ctx */ } fclose(log); return 0; }
void log_talloc_report(TALLOC_CTX *ctx) { FILE *fd; char const *null_ctx = NULL; int i = 0; if (ctx) { null_ctx = talloc_get_name(NULL); } fd = fdopen(default_log.fd, "w"); if (!fd) { ERROR("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno)); return; } if (!ctx) { talloc_report_full(NULL, fd); } else { do { INFO("Context level %i", i++); talloc_report_full(ctx, fd); } while ((ctx = talloc_parent(ctx)) && (talloc_get_name(ctx) != null_ctx)); /* Stop before we hit NULL ctx */ } fclose(fd); }
static void mangle_append_sub(char **s, char *m) { void *p = talloc_parent(*s); assert(p); // Kill prefix, for not making type names not ridiculous long. if (strncmp(m, MANGLE_PREFIX, strlen(MANGLE_PREFIX)) == 0) m = m + strlen(MANGLE_PREFIX); *s = talloc_asprintf_append_buffer(*s, "%zd_%s_", strlen(m), m); }
static int cli_trans_state_ptr_destructor(struct cli_trans_state **ptr) { struct cli_trans_state *state = *ptr; void *parent = talloc_parent(state); talloc_set_destructor(state, NULL); talloc_reparent(state, parent, state->req); talloc_free(state); return 0; }
cbuf* cbuf_swapptr(cbuf* b, char** ptr, size_t len) { void* p = talloc_parent(*ptr); SWAP(b->buf, *ptr, char*); talloc_steal(b, b->buf); talloc_steal(p, *ptr); b->size = talloc_get_size(b->buf); b->pos = (len == -1) ? strlen(b->buf) : len; assert(b->pos <= b->size); return b; }
int main(int argc, char *argv[]) { char **split, *str; void *ctx; plan_tests(16); split = strsplit(NULL, "hello world", " "); ok1(talloc_array_length(split) == 4); ok1(!strcmp(split[0], "hello")); ok1(!strcmp(split[1], "")); ok1(!strcmp(split[2], "world")); ok1(split[3] == NULL); talloc_free(split); split = strsplit(NULL, "hello world", "o "); ok1(talloc_array_length(split) == 6); ok1(!strcmp(split[0], "hell")); ok1(!strcmp(split[1], "")); ok1(!strcmp(split[2], "")); ok1(!strcmp(split[3], "w")); ok1(!strcmp(split[4], "rld")); ok1(split[5] == NULL); ctx = split; split = strsplit(ctx, "hello world", "o "); ok1(talloc_parent(split) == ctx); talloc_free(ctx); str = strjoin(NULL, (char **)substrings, ", "); ok1(!strcmp(str, "far, bar, baz, b, ba, z, ar, ")); ctx = str; str = strjoin(ctx, (char **)substrings, ""); ok1(!strcmp(str, "farbarbazbbazar")); ok1(talloc_parent(str) == ctx); talloc_free(ctx); return exit_status(); }
void generate(unsigned i, ir_rvalue* condition, exec_list *list) const { /* Just clone the rest of the deref chain when trying to get at the * underlying variable. */ void *mem_ctx = talloc_parent(base_ir); ir_rvalue *element = new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, NULL), new(mem_ctx) ir_constant(i)); ir_rvalue *variable = new(mem_ctx) ir_dereference_variable(this->var); ir_assignment *assignment = (is_write) ? new(mem_ctx) ir_assignment(element, variable, condition) : new(mem_ctx) ir_assignment(variable, element, condition); list->push_tail(assignment); }
void dsdb_make_schema_global(struct ldb_context *ldb) { struct dsdb_schema *schema = dsdb_get_schema(ldb); if (!schema) { return; } if (global_schema) { talloc_unlink(talloc_autofree_context(), global_schema); } /* we want the schema to be around permanently */ talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema); global_schema = schema; dsdb_set_global_schema(ldb); }
NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint16_t *recv_flags2, uint16_t **setup, uint8_t min_setup, uint8_t *num_setup, uint8_t **param, uint32_t min_param, uint32_t *num_param, uint8_t **data, uint32_t min_data, uint32_t *num_data) { NTSTATUS status; void *parent = talloc_parent(req); struct cli_trans_state *state = talloc_get_type(parent, struct cli_trans_state); bool map_dos_errors = true; status = smb1cli_trans_recv(req, mem_ctx, recv_flags2, setup, min_setup, num_setup, param, min_param, num_param, data, min_data, num_data); if (state) { map_dos_errors = state->cli->map_dos_errors; state->cli->raw_status = status; talloc_free(state->ptr); state = NULL; } if (NT_STATUS_IS_DOS(status) && map_dos_errors) { uint8_t eclass = NT_STATUS_DOS_CLASS(status); uint16_t ecode = NT_STATUS_DOS_CODE(status); /* * TODO: is it really a good idea to do a mapping here? * * The old cli_pull_error() also does it, so I do not change * the behavior yet. */ status = dos_to_ntstatus(eclass, ecode); } return status; }
cbuf* cbuf_copy(const cbuf* b) { cbuf* s = talloc(talloc_parent(b), cbuf); if (s == NULL) { return NULL; } s->buf = (char *)talloc_memdup(s, b->buf, b->size); /* only up to pos? */ /* XXX shallow did not work, because realloc */ /* fails with multiple references */ /* s->buf = talloc_reference(s, b->buf); */ if (s->buf == NULL) { cbuf_delete(s); return NULL; } s->size = b->size; s->pos = b->pos; return s; }
ir_rvalue * ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir) { ir_dereference_array *deref = ir->as_dereference_array(); ir_constant *ir_constant; if (!deref) return ir; if (deref->array->type->is_matrix() || deref->array->type->is_array()) return ir; assert(deref->array_index->type->base_type == GLSL_TYPE_INT); ir_constant = deref->array_index->constant_expression_value(); if (!ir_constant) return ir; void *ctx = talloc_parent(ir); this->progress = true; return new(ctx) ir_swizzle(deref->array, ir_constant->value.i[0], 0, 0, 0, 1); }
/* perform the receive side of a async dcerpc request */ NTSTATUS dcerpc_request_recv(struct rpc_request *req, TALLOC_CTX *mem_ctx, DATA_BLOB *stub_data) { NTSTATUS status; while (req->state != RPC_REQUEST_DONE) { struct tevent_context *ctx = dcerpc_event_context(req->p); if (event_loop_once(ctx) != 0) { return NT_STATUS_CONNECTION_DISCONNECTED; } } *stub_data = req->payload; status = req->status; if (stub_data->data) { stub_data->data = talloc_steal(mem_ctx, stub_data->data); } if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { req->p->last_fault_code = req->fault_code; } talloc_unlink(talloc_parent(req), req); return status; }
int talloc_free(void *ptr) { return talloc_unlink(talloc_parent(ptr), ptr); }
void *_talloc_steal(const void *new_ctx, const void *ptr) { return talloc_reparent(talloc_parent(ptr), new_ctx, ptr); }
ir_visitor_status loop_unroll_visitor::visit_leave(ir_loop *ir) { loop_variable_state *const ls = this->state->get(ir); int iterations; /* If we've entered a loop that hasn't been analyzed, something really, * really bad has happened. */ if (ls == NULL) { assert(ls != NULL); return visit_continue; } iterations = ls->max_iterations; /* Don't try to unroll loops where the number of iterations is not known * at compile-time. */ if (iterations < 0) return visit_continue; /* Don't try to unroll loops that have zillions of iterations either. */ if (iterations > max_iterations) return visit_continue; if (ls->num_loop_jumps > 1) return visit_continue; else if (ls->num_loop_jumps) { /* recognize loops in the form produced by ir_lower_jumps */ ir_instruction *last_ir = ((ir_instruction*)ir->body_instructions.get_tail()); assert(last_ir != NULL); ir_if *last_if = last_ir->as_if(); if (last_if) { bool continue_from_then_branch; /* Determine which if-statement branch, if any, ends with a break. * The branch that did *not* have the break will get a temporary * continue inserted in each iteration of the loop unroll. * * Note that since ls->num_loop_jumps is <= 1, it is impossible for * both branches to end with a break. */ ir_instruction *last = (ir_instruction *) last_if->then_instructions.get_tail(); if (last && last->ir_type == ir_type_loop_jump && ((ir_loop_jump*) last)->is_break()) { continue_from_then_branch = false; } else { last = (ir_instruction *) last_if->then_instructions.get_tail(); if (last && last->ir_type == ir_type_loop_jump && ((ir_loop_jump*) last)->is_break()) continue_from_then_branch = true; else /* Bail out if neither if-statement branch ends with a break. */ return visit_continue; } /* Remove the break from the if-statement. */ last->remove(); void *const mem_ctx = talloc_parent(ir); ir_instruction *ir_to_replace = ir; for (int i = 0; i < iterations; i++) { exec_list copy_list; copy_list.make_empty(); clone_ir_list(mem_ctx, ©_list, &ir->body_instructions); last_if = ((ir_instruction*)copy_list.get_tail())->as_if(); assert(last_if); ir_to_replace->insert_before(©_list); ir_to_replace->remove(); /* placeholder that will be removed in the next iteration */ ir_to_replace = new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue); exec_list *const list = (continue_from_then_branch) ? &last_if->then_instructions : &last_if->else_instructions; list->push_tail(ir_to_replace); } ir_to_replace->remove(); this->progress = true; return visit_continue; } else if (last_ir->ir_type == ir_type_loop_jump && ((ir_loop_jump *)last_ir)->is_break()) { /* If the only loop-jump is a break at the end of the loop, the loop * will execute exactly once. Remove the break, set the iteration * count, and fall through to the normal unroller. */ last_ir->remove(); iterations = 1; this->progress = true; } else return visit_continue; } void *const mem_ctx = talloc_parent(ir); for (int i = 0; i < iterations; i++) { exec_list copy_list; copy_list.make_empty(); clone_ir_list(mem_ctx, ©_list, &ir->body_instructions); ir->insert_before(©_list); } /* The loop has been replaced by the unrolled copies. Remove the original * loop from the IR sequence. */ ir->remove(); this->progress = true; return visit_continue; }
/** Registers signal handlers to execute panic_action on fatal signal * * May be called multiple time to change the panic_action/program. * * @param cmd to execute on fault. If present %p will be substituted * for the parent PID before the command is executed, and %e * will be substituted for the currently running program. * @param program Name of program currently executing (argv[0]). * @return 0 on success -1 on failure. */ int fr_fault_setup(char const *cmd, char const *program) { static bool setup = false; char *out = panic_action; size_t left = sizeof(panic_action); char const *p = cmd; char const *q; if (cmd) { size_t ret; /* Substitute %e for the current program */ while ((q = strstr(p, "%e"))) { out += ret = snprintf(out, left, "%.*s%s", (int) (q - p), p, program ? program : ""); if (left <= ret) { oob: fr_strerror_printf("Panic action too long"); return -1; } left -= ret; p = q + 2; } if (strlen(p) >= left) goto oob; strlcpy(out, p, left); } else { *panic_action = '\0'; } /* * Check for administrator sanity. */ if (fr_fault_check_permissions() < 0) return -1; /* Unsure what the side effects of changing the signal handler mid execution might be */ if (!setup) { char *env; fr_debug_state_t debug_state; /* * Installing signal handlers interferes with some debugging * operations. Give the developer control over whether the * signal handlers are installed or not. */ env = getenv("DEBUG"); if (!env || (strcmp(env, "no") == 0)) { debug_state = DEBUG_STATE_NOT_ATTACHED; } else if (!strcmp(env, "auto") || !strcmp(env, "yes")) { /* * Figure out if we were started under a debugger */ if (fr_debug_state < 0) fr_debug_state = fr_get_debug_state(); debug_state = fr_debug_state; } else { debug_state = DEBUG_STATE_ATTACHED; } talloc_set_log_fn(_fr_talloc_log); /* * These signals can't be properly dealt with in the debugger * if we set our own signal handlers. */ switch (debug_state) { default: #ifndef NDEBUG FR_FAULT_LOG("Debugger check failed: %s", fr_strerror()); FR_FAULT_LOG("Signal processing in debuggers may not work as expected"); #endif /* FALL-THROUGH */ case DEBUG_STATE_NOT_ATTACHED: #ifdef SIGABRT if (fr_set_signal(SIGABRT, fr_fault) < 0) return -1; /* * Use this instead of abort so we get a * full backtrace with broken versions of LLDB */ talloc_set_abort_fn(_fr_talloc_fault); #endif #ifdef SIGILL if (fr_set_signal(SIGILL, fr_fault) < 0) return -1; #endif #ifdef SIGFPE if (fr_set_signal(SIGFPE, fr_fault) < 0) return -1; #endif #ifdef SIGSEGV if (fr_set_signal(SIGSEGV, fr_fault) < 0) return -1; #endif break; case DEBUG_STATE_ATTACHED: break; } /* * Needed for memory reports */ { TALLOC_CTX *tmp; bool *marker; tmp = talloc(NULL, bool); talloc_null_ctx = talloc_parent(tmp); talloc_free(tmp); /* * Disable null tracking on exit, else valgrind complains */ talloc_autofree_ctx = talloc_autofree_context(); marker = talloc(talloc_autofree_ctx, bool); talloc_set_destructor(marker, _fr_disable_null_tracking); } #if defined(HAVE_MALLOPT) && !defined(NDEBUG) /* * If were using glibc malloc > 2.4 this scribbles over * uninitialised and freed memory, to make memory issues easier * to track down. */ if (!getenv("TALLOC_FREE_FILL")) mallopt(M_PERTURB, 0x42); mallopt(M_CHECK_ACTION, 3); #endif #if defined(HAVE_EXECINFO) && defined(__GNUC__) && !defined(NDEBUG) /* * We need to pre-load lgcc_s, else we can get into a deadlock * in fr_fault, as backtrace() attempts to dlopen it. * * Apparently there's a performance impact of loading lgcc_s, * so only do it if this is a debug build. * * See: https://sourceware.org/bugzilla/show_bug.cgi?id=16159 */ { void *stack[10]; backtrace(stack, 10); } #endif }