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 bool test_talloc_ptrtype(const struct torture_context *ctx) { void *top = talloc_new(ctx); struct struct1 { int foo; int bar; } *s1, *s2, **s3, ***s4; const char *location1; const char *location2; const char *location3; const char *location4; bool ret = false; if (!top) goto out; s1 = talloc_ptrtype(top, s1);location1 = __location__; if (!s1) goto out; ok1(talloc_get_size(s1) == sizeof(struct struct1)); ok1(strcmp(location1, talloc_get_name(s1)) == 0); s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; if (!s2) goto out; ok1(talloc_get_size(s2) == (sizeof(struct struct1) * 10)); ok1(strcmp(location2, talloc_get_name(s2)) == 0); s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; if (!s3) goto out; ok1(talloc_get_size(s3) == (sizeof(struct struct1 *) * 10)); torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), "talloc_array_ptrtype() sets the wrong name"); s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; if (!s4) goto out; ok1(talloc_get_size(s4) == (sizeof(struct struct1 **) * 10)); torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), "talloc_array_ptrtype() sets the wrong name"); ret = true; out: talloc_free(top); return ret; }
/** 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; }
static void msg_pool_usage_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_s) { const char *name = talloc_get_name(ptr); struct msg_pool_usage_state *state = (struct msg_pool_usage_state *)_s; if (is_ref) { sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen, "%*sreference to: %s\n", depth*4, "", name); return; } if (depth == 0) { sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen, "%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", (max_depth < 0 ? "full " :""), name, (unsigned long)talloc_total_size(ptr), (unsigned long)talloc_total_blocks(ptr)); return; } sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", depth*4, "", name, (unsigned long)talloc_total_size(ptr), (unsigned long)talloc_total_blocks(ptr), talloc_reference_count(ptr)); }
/** Print a list of valuepairs to the request list. * * @param[in] level Debug level (1-4). * @param[in] request to read logging params from. * @param[in] vp to print. */ void rdebug_pair_list(int level, REQUEST *request, VALUE_PAIR *vp) { vp_cursor_t cursor; char buffer[256]; if (!vp || !request || !request->log.func) return; if (!radlog_debug_enabled(L_DBG, level, request)) return; for (vp = fr_cursor_init(&cursor, &vp); vp; vp = fr_cursor_next(&cursor)) { /* * Take this opportunity to verify all the VALUE_PAIRs are still valid. */ if (!talloc_get_type(vp, VALUE_PAIR)) { REDEBUG("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp)); fr_log_talloc_report(vp); rad_assert(0); } vp_prints(buffer, sizeof(buffer), vp); RDEBUGX(level, "\t%s", buffer); } }
/** Inserts a backtrace marker into the provided context * * Allows for maximum laziness and will initialise a circular buffer if one has not already been created. * * Code augmentation should look something like: @verbatim // Create a static cbuffer pointer, the first call to backtrace_attach will initialise it static fr_cbuff_t *my_obj_bt; my_obj_t *alloc_my_obj(TALLOC_CTX *ctx) { my_obj_t *this; this = talloc(ctx, my_obj_t); // Attach backtrace marker to object backtrace_attach(&my_obj_bt, this); return this; } @endverbatim * * Then, later when a double free occurs: @verbatim (gdb) call backtrace_print(&my_obj_bt, <pointer to double freed memory>) @endverbatim * * which should print a limited backtrace to stderr. Note, this backtrace will not include any argument * values, but should at least show the code path taken. * * @param cbuff this should be a pointer to a static *fr_cbuff. * @param obj we want to generate a backtrace for. */ fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj) { fr_bt_marker_t *marker; if (*cbuff == NULL) { PTHREAD_MUTEX_LOCK(&fr_debug_init); /* Check again now we hold the mutex - eww*/ if (*cbuff == NULL) *cbuff = fr_cbuff_alloc(NULL, MAX_BT_CBUFF, true); PTHREAD_MUTEX_UNLOCK(&fr_debug_init); } marker = talloc(obj, fr_bt_marker_t); if (!marker) { return NULL; } marker->obj = (void *) obj; marker->cbuff = *cbuff; fprintf(stderr, "Backtrace attached to %s %p\n", talloc_get_name(obj), obj); /* * Generate the backtrace for memory allocation */ fr_backtrace_do(marker); talloc_set_destructor(marker, fr_backtrace_do); return marker; }
static void print_packet(FILE *fp, RADIUS_PACKET *packet) { VALUE_PAIR *vp; vp_cursor_t cursor; if (!packet) { fprintf(fp, "\n"); return; } fprintf(fp, "%s\n", fr_packet_codes[packet->code]); for (vp = fr_cursor_init(&cursor, &packet->vps); vp; vp = fr_cursor_next(&cursor)) { /* * Take this opportunity to verify all the VALUE_PAIRs are still valid. */ if (!talloc_get_type(vp, VALUE_PAIR)) { ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp)); fr_log_talloc_report(vp); rad_assert(0); } vp_print(fp, vp); } fflush(fp); }
void *_policy_handle_find(struct pipes_struct *p, const struct policy_handle *hnd, uint32_t access_required, uint32_t *paccess_granted, const char *name, const char *location, NTSTATUS *pstatus) { struct policy *pol; void *data; pol = find_policy_by_hnd_internal(p, hnd, &data); if (pol == NULL) { *pstatus = NT_STATUS_INVALID_HANDLE; return NULL; } if (strcmp(name, talloc_get_name(data)) != 0) { DEBUG(10, ("expected %s, got %s\n", name, talloc_get_name(data))); *pstatus = NT_STATUS_INVALID_HANDLE; return NULL; } if ((access_required & pol->access_granted) != access_required) { if (geteuid() == sec_initial_uid()) { DEBUG(4, ("%s: ACCESS should be DENIED (granted: " "%#010x; required: %#010x)\n", location, pol->access_granted, access_required)); DEBUGADD(4,("but overwritten by euid == 0\n")); goto okay; } DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: " "%#010x)\n", location, pol->access_granted, access_required)); *pstatus = NT_STATUS_ACCESS_DENIED; return NULL; } okay: DEBUG(10, ("found handle of type %s\n", talloc_get_name(data))); if (paccess_granted != NULL) { *paccess_granted = pol->access_granted; } *pstatus = NT_STATUS_OK; return data; }
/* a type checking varient of idr_find */ static void *_idr_find_type(struct idr_context *idp, int id, const char *type, const char *location) { void *p = idr_find(idp, id); if (p && talloc_check_name(p, type) == NULL) { DEBUG(DEBUG_ERR,("%s idr_find_type expected type %s but got %s\n", location, type, talloc_get_name(p))); return NULL; } return p; }
char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) { return talloc_asprintf(mem_ctx, "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " " state[%s (%p)] timer[%p]", req, req->internal.create_location, req->internal.state, (unsigned long long)req->internal.error, (unsigned long long)req->internal.error, talloc_get_name(req->data), req->data, req->internal.timer ); }
_PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name) { void *ptr = _pytalloc_get_ptr(py_obj); void *type_obj = talloc_check_name(ptr, type_name); if (type_obj == NULL) { const char *name = talloc_get_name(ptr); PyErr_Format(PyExc_TypeError, "pytalloc: expected %s, got %s", type_name, name); return NULL; } return ptr; }
/* tell the caller we have an error */ static void packet_error(struct packet_context *pc, NTSTATUS status) { pc->sock = NULL; if (pc->error_handler) { pc->error_handler(pc->private_data, status); return; } /* default error handler is to free the callers private pointer */ if (!NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { DEBUG(0,("packet_error on %s - %s\n", talloc_get_name(pc->private_data), nt_errstr(status))); } talloc_free(pc->private_data); return; }
static bool test_free_children(void) { void *root; const char *p1, *p2, *name, *name2; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo1"); p2 = talloc_strdup(p1, "foo2"); talloc_set_name(p1, "%s", "testname"); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); if (strcmp(talloc_get_name(p1), "testname") != 0) { return false; } talloc_set_name(p1, "%s", "testname"); name = talloc_get_name(p1); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); torture_assert("name", name == talloc_get_name(p1), "name ptr changed"); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 2); /* note that this does not free the old child name */ talloc_set_name_const(p1, "testname2"); name2 = talloc_get_name(p1); /* but this does */ talloc_free_children(p1); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 1); talloc_report_full(root, stdout); talloc_free(root); return true; }
/** Print a list of valuepairs to stderr or error log. * * @param[in] vp to print. */ void debug_pair_list(VALUE_PAIR *vp) { vp_cursor_t cursor; if (!vp || !debug_flag || !fr_log_fp) return; for (vp = paircursor(&cursor, &vp); vp; vp = pairnext(&cursor)) { /* * Take this opportunity to verify all the VALUE_PAIRs are still valid. */ if (!talloc_get_type(vp, VALUE_PAIR)) { ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp)); log_talloc_report(vp); rad_assert(0); } vp_print(fr_log_fp, vp); } fflush(fr_log_fp); }
QDebug TallocContext::error(const QString &caller) const { static QString prefix = QString::fromAscii("%1.%2"); QString talloc = QString::fromAscii(talloc_get_name(m_ctx)); return qCritical() << prefix.arg(talloc).arg(caller); }
static REQUEST *request_setup(FILE *fp) { VALUE_PAIR *vp; REQUEST *request; vp_cursor_t cursor; /* * Create and initialize the new request. */ request = request_alloc(NULL); request->packet = rad_alloc(request, false); if (!request->packet) { ERROR("No memory"); talloc_free(request); return NULL; } request->reply = rad_alloc(request, false); if (!request->reply) { ERROR("No memory"); talloc_free(request); return NULL; } request->listener = listen_alloc(request); request->client = client_alloc(request); request->number = 0; request->master_state = REQUEST_ACTIVE; request->child_state = REQUEST_RUNNING; request->handle = NULL; request->server = talloc_typed_strdup(request, "default"); request->root = &main_config; /* * Read packet from fp */ if (readvp2(request->packet, &request->packet->vps, fp, &filedone) < 0) { fr_perror("unittest"); talloc_free(request); return NULL; } /* * Set the defaults for IPs, etc. */ request->packet->code = PW_CODE_ACCESS_REQUEST; request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->src_port = 18120; request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->dst_port = 1812; /* * Copied from radclient */ #if 1 /* * Fix up Digest-Attributes issues */ for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { /* * Double quoted strings get marked up as xlat expansions, * but we don't support that here. */ if (vp->type == VT_XLAT) { vp->vp_strvalue = vp->value.xlat; vp->value.xlat = NULL; vp->type = VT_DATA; } if (!vp->da->vendor) switch (vp->da->attr) { default: break; /* * Allow it to set the packet type in * the attributes read from the file. */ case PW_PACKET_TYPE: request->packet->code = vp->vp_integer; break; case PW_PACKET_DST_PORT: request->packet->dst_port = (vp->vp_integer & 0xffff); break; case PW_PACKET_DST_IP_ADDRESS: request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; break; case PW_PACKET_DST_IPV6_ADDRESS: request->packet->dst_ipaddr.af = AF_INET6; request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr; break; case PW_PACKET_SRC_PORT: request->packet->src_port = (vp->vp_integer & 0xffff); break; case PW_PACKET_SRC_IP_ADDRESS: request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; break; case PW_PACKET_SRC_IPV6_ADDRESS: request->packet->src_ipaddr.af = AF_INET6; request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr; break; case PW_CHAP_PASSWORD: { int i, already_hex = 0; /* * If it's 17 octets, it *might* be already encoded. * Or, it might just be a 17-character password (maybe UTF-8) * Check it for non-printable characters. The odds of ALL * of the characters being 32..255 is (1-7/8)^17, or (1/8)^17, * or 1/(2^51), which is pretty much zero. */ if (vp->length == 17) { for (i = 0; i < 17; i++) { if (vp->vp_octets[i] < 32) { already_hex = 1; break; } } } /* * Allow the user to specify ASCII or hex CHAP-Password */ if (!already_hex) { uint8_t *p; size_t len, len2; len = len2 = vp->length; if (len2 < 17) len2 = 17; p = talloc_zero_array(vp, uint8_t, len2); memcpy(p, vp->vp_strvalue, len); rad_chap_encode(request->packet, p, fr_rand() & 0xff, vp); vp->vp_octets = p; vp->length = 17; } } break; case PW_DIGEST_REALM: case PW_DIGEST_NONCE: case PW_DIGEST_METHOD: case PW_DIGEST_URI: case PW_DIGEST_QOP: case PW_DIGEST_ALGORITHM: case PW_DIGEST_BODY_DIGEST: case PW_DIGEST_CNONCE: case PW_DIGEST_NONCE_COUNT: case PW_DIGEST_USER_NAME: /* overlapping! */ { DICT_ATTR const *da; uint8_t *p, *q; p = talloc_array(vp, uint8_t, vp->length + 2); memcpy(p + 2, vp->vp_octets, vp->length); p[0] = vp->da->attr - PW_DIGEST_REALM + 1; vp->length += 2; p[1] = vp->length; da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0); rad_assert(da != NULL); vp->da = da; /* * Re-do pairmemsteal ourselves, * because we play games with * vp->da, and pairmemsteal goes * to GREAT lengths to sanitize * and fix and change and * double-check the various * fields. */ memcpy(&q, &vp->vp_octets, sizeof(q)); talloc_free(q); vp->vp_octets = talloc_steal(vp, p); vp->type = VT_DATA; VERIFY_VP(vp); } break; } } /* loop over the VP's we read in */ #endif if (debug_flag) { for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { /* * Take this opportunity to verify all the VALUE_PAIRs are still valid. */ if (!talloc_get_type(vp, VALUE_PAIR)) { ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp)); fr_log_talloc_report(vp); rad_assert(0); } vp_print(fr_log_fp, vp); } fflush(fr_log_fp); } /* * FIXME: set IPs, etc. */ request->packet->code = PW_CODE_ACCESS_REQUEST; request->packet->src_ipaddr.af = AF_INET; request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->src_port = 18120; request->packet->dst_ipaddr.af = AF_INET; request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK); request->packet->dst_port = 1812; /* * Build the reply template from the request. */ request->reply->sockfd = request->packet->sockfd; request->reply->dst_ipaddr = request->packet->src_ipaddr; request->reply->src_ipaddr = request->packet->dst_ipaddr; request->reply->dst_port = request->packet->src_port; request->reply->src_port = request->packet->dst_port; request->reply->id = request->packet->id; request->reply->code = 0; /* UNKNOWN code */ memcpy(request->reply->vector, request->packet->vector, sizeof(request->reply->vector)); request->reply->vps = NULL; request->reply->data = NULL; request->reply->data_len = 0; /* * Debugging */ request->log.lvl = debug_flag; request->log.func = vradlog_request; request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY); request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY); return request; }
/* miscellaneous tests to try to get a higher test coverage percentage */ static bool test_misc(void) { void *root, *p1; char *p2; double *d; const char *name; printf("test: misc\n# MISCELLANEOUS\n"); root = talloc_new(NULL); p1 = talloc_size(root, 0x7fffffff); torture_assert("misc", !p1, "failed: large talloc allowed\n"); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); p2 = talloc_strdup(p1, "foo"); torture_assert("misc", talloc_unlink(root, p2) == -1, "failed: talloc_unlink() of non-reference context should return -1\n"); torture_assert("misc", talloc_unlink(p1, p2) == 0, "failed: talloc_unlink() of parent should succeed\n"); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); name = talloc_set_name(p1, "my name is %s", "foo"); torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", "failed: wrong name after talloc_set_name(my name is foo)"); torture_assert_str_equal("misc", talloc_get_name(p1), name, "failed: wrong name after talloc_set_name(my name is foo)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_set_name_const(p1, NULL); torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", "failed: wrong name after talloc_set_name(NULL)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); torture_assert("misc", talloc_free(NULL) == -1, "talloc_free(NULL) should give -1\n"); talloc_set_destructor(p1, fail_destructor); torture_assert("misc", talloc_free(p1) == -1, "Failed destructor should cause talloc_free to fail\n"); talloc_set_destructor(p1, NULL); talloc_report(root, stderr); p2 = (char *)talloc_zero_size(p1, 20); torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); talloc_free(p2); torture_assert("misc", talloc_strdup(root, NULL) == NULL, "failed: strdup on NULL should give NULL\n"); p2 = talloc_strndup(p1, "foo", 2); torture_assert("misc", strcmp("fo", p2) == 0, "strndup doesn't work\n"); p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); torture_assert("misc", strcmp("food", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); torture_assert("misc", strcmp("hello world", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); talloc_free(p2); d = talloc_array(p1, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); d = talloc_realloc(p1, d, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); talloc_free(p1); CHECK_BLOCKS("misc", root, 1); p1 = talloc_named(root, 100, "%d bytes", 100); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(root, p1); p1 = talloc_init("%d bytes", 200); p2 = talloc_asprintf(p1, "my test '%s'", "string"); torture_assert_str_equal("misc", p2, "my test 'string'", "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); CHECK_BLOCKS("misc", p1, 3); CHECK_SIZE("misc", p2, 17); CHECK_BLOCKS("misc", root, 1); talloc_unlink(NULL, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(p1, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(p1, p2); talloc_unlink(root, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(NULL, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p2); talloc_unlink(root, p1); /* Test that talloc_unlink is a no-op */ torture_assert("misc", talloc_unlink(root, NULL) == -1, "failed: talloc_unlink(root, NULL) == -1\n"); talloc_report(root, stderr); talloc_report(NULL, stderr); CHECK_SIZE("misc", root, 0); talloc_free(root); CHECK_SIZE("misc", NULL, 0); talloc_enable_null_tracking_no_autofree(); talloc_enable_leak_report(); talloc_enable_leak_report_full(); printf("success: misc\n"); return true; }
static bool test_talloc_ptrtype(void) { void *top = talloc_new(NULL); struct struct1 { int foo; int bar; } *s1, *s2, **s3, ***s4; const char *location1; const char *location2; const char *location3; const char *location4; printf("test: ptrtype\n# TALLOC PTRTYPE\n"); s1 = talloc_ptrtype(top, s1);location1 = __location__; if (talloc_get_size(s1) != sizeof(struct struct1)) { printf("failure: ptrtype [\n" "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n" "]\n", (unsigned long)talloc_get_size(s1), (unsigned long)sizeof(struct struct1)); return false; } if (strcmp(location1, talloc_get_name(s1)) != 0) { printf("failure: ptrtype [\n" "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", talloc_get_name(s1), location1); return false; } s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s2), (unsigned long)(sizeof(struct struct1)*10)); return false; } if (strcmp(location2, talloc_get_name(s2)) != 0) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", talloc_get_name(s2), location2); return false; } s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s3), (unsigned long)(sizeof(struct struct1 *)*10)); return false; } torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), "talloc_array_ptrtype() sets the wrong name"); s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { printf("failure: ptrtype [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s4), (unsigned long)(sizeof(struct struct1 **)*10)); return false; } torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), "talloc_array_ptrtype() sets the wrong name"); talloc_free(top); printf("success: ptrtype\n"); return true; }
const Object_Class* OBJECT_CLASS_PTR(Object) { static Object_Class the_class = { .magic = CLASS_MAGIC, .name = "Object", .super = NULL, .size = sizeof (Object), .initializer = NULL, .finalize = NULL, }; static const Object the_default_object = { ._.isa = &the_class }; if (the_class.initializer == NULL) { _ObjectClass_Lock(); the_class.initializer = &the_default_object; _ObjectClass_Unlock(); } return &the_class; } const Object_Class* OBJECT_BASE_CLASS_PTR(Object) { return OBJECT_CLASS_PTR(Object); } /***************************************************************************** * _Object_check_alloc *****************************************************************************/ static const char* const NAME_UNDER_CONSTRUCTION = "under construction"; Object* _Object_check_alloc (void* talloc_context, const Object_Class* isa) { /* * 1) check if we have a "real" context, or an object already * allocated and under construction. */ if (talloc_get_name (talloc_context) == NAME_UNDER_CONSTRUCTION) { return talloc_context; // ----------> } /* * 2) Allocate a new object */ if (isa == NULL) { Log_Print (LOG_ERROR, "Object CreateBase NULL isa class"); return NULL; // ----------> } Object* obj = talloc_named_const (talloc_context, isa->size, NAME_UNDER_CONSTRUCTION); if (obj == NULL) { Log_Print (LOG_ERROR, "Object CreateBase Out of Memory"); return NULL; // ----------> } // Init fields to default values if (isa->initializer) memcpy (obj, isa->initializer, isa->size); _OBJECT_SET_CLASS (obj, isa); // Register destructor talloc_set_destructor (obj, destroy); return obj; } /***************************************************************************** * Object_Create *****************************************************************************/ Object* Object_Create (void* parent_context, void* unused) { (void) unused; Object* self = _Object_check_alloc (parent_context, OBJECT_BASE_CLASS_PTR (Object)); // Finalize construction if (self != NULL) talloc_set_name_const (self, OBJECT_GET_CLASS_NAME (self)); return self; }