void collect_garbage() { if (!chunks) return; /* minor collection: */ mark_and_sweep_from_roots(); /* The minor collection above relies on having no references from old object to new objects; this is not a general-purpose GC. If such references were allowed, we'd have to add them as roots. */ /* move non-empty chunks to old generation: */ if (chunks) { struct gc_chunk *prev_c = NULL, *next; for (struct gc_chunk *c = chunks; c; c = next) { next = c->next; if (c->num_marked_nodes == 0) { /* This chunk is empty, so free it */ raw_free(c->mem, NODES_PER_CHUNK * sizeof(struct gc_node)); raw_free(c, sizeof(struct gc_chunk)); if (!prev_c) chunks = next; } else { /* Keep this chunk, now as an old-generation chunk */ num_gen1_chunks++; if (prev_c) prev_c->next = c; prev_c = c; } c = next; } if (prev_c) { prev_c->next = gen1_chunks; gen1_chunks = chunks; } chunks = NULL; free_list = NULL; } if (num_gen1_chunks >= (last_major_gen1_chunks * 2)) { /* perform major collection by moving all old-generation chunks back to the "new" generation, and GC again */ // printf("Major GC\n"); last_major_gen1_chunks = num_gen1_chunks; chunks = gen1_chunks; gen1_chunks = NULL; num_gen1_chunks = 0; collect_garbage(); } }
/** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow * that with a backtrace log. */ void log_backtrace(int severity, int domain, const char *msg) { size_t depth; char **symbols; size_t i; tor_mutex_acquire(&cb_buf_mutex); depth = backtrace(cb_buf, MAX_DEPTH); symbols = backtrace_symbols(cb_buf, (int)depth); tor_log(severity, domain, "%s. Stack trace:", msg); if (!symbols) { /* LCOV_EXCL_START -- we can't provoke this. */ tor_log(severity, domain, " Unable to generate backtrace."); goto done; /* LCOV_EXCL_STOP */ } for (i=0; i < depth; ++i) { tor_log(severity, domain, " %s", symbols[i]); } raw_free(symbols); done: tor_mutex_release(&cb_buf_mutex); }
RAW *ben_enc(BEN * node) { RAW *raw = raw_init(); /* Calculate size of ben data */ raw->size = ben_enc_size(node); if (raw->size <= 0) { raw_free(raw); return NULL; } /* Encode ben object */ raw->code = (UCHAR *) myalloc(raw->size * sizeof(UCHAR)); raw->p = ben_enc_rec(node, raw->code); if (raw->p == NULL || (LONG) (raw->p - raw->code) != raw->size) { raw_free(raw); return NULL; } return raw; }
void FvDebugMsgHelper::MessageBackTrace() { void ** traceBuffer = new void*[MAX_DEPTH]; FvUInt32 depth = backtrace( traceBuffer, MAX_DEPTH ); char ** traceStringBuffer = backtrace_symbols( traceBuffer, depth ); for (FvUInt32 i = 0; i < depth; i++) { this->message( "Stack: #%d %s\n", i, traceStringBuffer[i] ); } #ifdef ENABLE_MEMTRACKER raw_free( traceStringBuffer ); #else free( traceStringBuffer ); #endif delete[] traceBuffer; }
/** Install signal handlers as needed so that when we crash, we produce a * useful stack trace. Return 0 on success, -1 on failure. */ static int install_bt_handler(void) { int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, SIGIO, -1 }; int i, rv=0; struct sigaction sa; tor_mutex_init(&cb_buf_mutex); memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = crash_handler; sa.sa_flags = SA_SIGINFO; sigfillset(&sa.sa_mask); for (i = 0; trap_signals[i] >= 0; ++i) { if (sigaction(trap_signals[i], &sa, NULL) == -1) { /* LCOV_EXCL_START */ log_warn(LD_BUG, "Sigaction failed: %s", strerror(errno)); rv = -1; /* LCOV_EXCL_STOP */ } } { /* Now, generate (but do not log) a backtrace. This ensures that * libc has pre-loaded the symbols we need to dump things, so that later * reads won't be denied by the sandbox code */ char **symbols; size_t depth = backtrace(cb_buf, MAX_DEPTH); symbols = backtrace_symbols(cb_buf, (int) depth); if (symbols) raw_free(symbols); } return rv; }
void test_page(void * pParam) { void *test1; void *test2; PAGETBL *pg; int count = 0; raw_page_init(test_page_mem, test_page_mem + 1024*1024); pg = system_page_table_get(); vc_port_printf("111 max page is %d, free page is %d, top page addr is %p\n", pg->maxpage, pg->freepage, pg->top_page); raw_malloc_init(); test1 = raw_malloc(188888); test2 = raw_malloc(18888); pg = system_page_table_get(); vc_port_printf("222 max page is %d, free page is %d, top page addr is %p\n", pg->maxpage, pg->freepage, pg->top_page); raw_free(test2); pg = system_page_table_get(); vc_port_printf("333 max page is %d, free page is %d, top page addr is %p\n", pg->maxpage, pg->freepage, pg->top_page); raw_free(test1); pg = system_page_table_get(); vc_port_printf("4444 max page is %d, free page is %d, top page addr is %p\n", pg->maxpage, pg->freepage, pg->top_page); while (1) { test1 = raw_page_allocate(25); if (test1 == 0) { vc_port_printf("RAW_NO_MEMORY\n"); RAW_ASSERT(0); } test2 = raw_page_allocate(25); if (test2 == 0) { vc_port_printf("RAW_NO_MEMORY\n"); RAW_ASSERT(0); } raw_page_free(test2); vc_port_printf("page success is %d\n", count++); } }
/** * Read the measured bandwidth list <b>from_file</b>: * - store all the headers in <b>bw_file_headers</b>, * - apply bandwidth lines to the list of vote_routerstatus_t in * <b>routerstatuses</b>, * - cache bandwidth lines for dirserv_get_bandwidth_for_router(), * - expire old entries in the measured bandwidth cache, and * - store the DIGEST_SHA256 of the contents of the file in <b>digest_out</b>. * * Returns -1 on error, 0 otherwise. * * If the file can't be read, or is empty: * - <b>bw_file_headers</b> is empty, * - <b>routerstatuses</b> is not modified, * - the measured bandwidth cache is not modified, and * - <b>digest_out</b> is the zero-byte digest. * * Otherwise, if there is an error later in the file: * - <b>bw_file_headers</b> contains all the headers up to the error, * - <b>routerstatuses</b> is updated with all the relay lines up to the error, * - the measured bandwidth cache is updated with all the relay lines up to * the error, * - if the timestamp is valid and recent, old entries in the measured * bandwidth cache are expired, and * - <b>digest_out</b> is the digest up to the first read error (if any). * The digest is taken over all the readable file contents, even if the * file is outdated or unparseable. */ int dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses, smartlist_t *bw_file_headers, uint8_t *digest_out) { FILE *fp = tor_fopen_cloexec(from_file, "r"); int applied_lines = 0; time_t file_time, now; int ok; /* This flag will be 1 only when the first successful bw measurement line * has been encountered, so that measured_bw_line_parse don't give warnings * if there are additional header lines, as introduced in Bandwidth List spec * version 1.1.0 */ int line_is_after_headers = 0; int rv = -1; char *line = NULL; size_t n = 0; crypto_digest_t *digest = crypto_digest256_new(DIGEST_SHA256); if (fp == NULL) { log_warn(LD_CONFIG, "Can't open bandwidth file at configured location: %s", from_file); goto err; } if (tor_getline(&line,&n,fp) <= 0) { log_warn(LD_DIRSERV, "Empty bandwidth file"); goto err; } /* If the line could be gotten, add it to the digest */ crypto_digest_add_bytes(digest, (const char *) line, strlen(line)); if (!strlen(line) || line[strlen(line)-1] != '\n') { log_warn(LD_DIRSERV, "Long or truncated time in bandwidth file: %s", escaped(line)); /* Continue adding lines to the digest. */ goto continue_digest; } line[strlen(line)-1] = '\0'; file_time = (time_t)tor_parse_ulong(line, 10, 0, ULONG_MAX, &ok, NULL); if (!ok) { log_warn(LD_DIRSERV, "Non-integer time in bandwidth file: %s", escaped(line)); goto continue_digest; } now = approx_time(); if ((now - file_time) > MAX_MEASUREMENT_AGE) { log_warn(LD_DIRSERV, "Bandwidth measurement file stale. Age: %u", (unsigned)(time(NULL) - file_time)); goto continue_digest; } /* If timestamp was correct and bw_file_headers is not NULL, * add timestamp to bw_file_headers */ if (bw_file_headers) smartlist_add_asprintf(bw_file_headers, "timestamp=%lu", (unsigned long)file_time); if (routerstatuses) smartlist_sort(routerstatuses, compare_vote_routerstatus_entries); while (!feof(fp)) { measured_bw_line_t parsed_line; if (tor_getline(&line, &n, fp) >= 0) { crypto_digest_add_bytes(digest, (const char *) line, strlen(line)); if (measured_bw_line_parse(&parsed_line, line, line_is_after_headers) != -1) { /* This condition will be true when the first complete valid bw line * has been encountered, which means the end of the header lines. */ line_is_after_headers = 1; /* Also cache the line for dirserv_get_bandwidth_for_router() */ dirserv_cache_measured_bw(&parsed_line, file_time); if (measured_bw_line_apply(&parsed_line, routerstatuses) > 0) applied_lines++; /* if the terminator is found, it is the end of header lines, set the * flag but do not store anything */ } else if (strcmp(line, BW_FILE_HEADERS_TERMINATOR) == 0) { line_is_after_headers = 1; /* if the line was not a correct relay line nor the terminator and * the end of the header lines has not been detected yet * and it is key_value and bw_file_headers did not reach the maximum * number of headers, * then assume this line is a header and add it to bw_file_headers */ } else if (bw_file_headers && (line_is_after_headers == 0) && string_is_key_value(LOG_DEBUG, line) && !strchr(line, ' ') && (smartlist_len(bw_file_headers) < MAX_BW_FILE_HEADER_COUNT_IN_VOTE)) { line[strlen(line)-1] = '\0'; smartlist_add_strdup(bw_file_headers, line); }; } } /* Now would be a nice time to clean the cache, too */ dirserv_expire_measured_bw_cache(now); log_info(LD_DIRSERV, "Bandwidth measurement file successfully read. " "Applied %d measurements.", applied_lines); rv = 0; continue_digest: /* Continue parsing lines to return the digest of the Bandwidth File. */ while (!feof(fp)) { if (tor_getline(&line, &n, fp) >= 0) { crypto_digest_add_bytes(digest, (const char *) line, strlen(line)); } } err: if (line) { // we need to raw_free this buffer because we got it from tor_getdelim() raw_free(line); } if (fp) fclose(fp); if (digest_out) crypto_digest_get_digest(digest, (char *) digest_out, DIGEST256_LEN); crypto_digest_free(digest); return rv; }