void sd_cleanup_crash_handler() { if (g_curdir) STD_FREE(g_curdir); if (g_cmdline) STD_FREE(g_cmdline); }
void gc_verifier_metadata_destruct(Heap_Verifier* heap_verifier) { Heap_Verifier_Metadata* metadata = heap_verifier->heap_verifier_metadata; sync_pool_destruct(metadata->free_task_pool); sync_pool_destruct(metadata->free_set_pool); sync_pool_destruct(metadata->mark_task_pool); sync_pool_destruct(metadata->root_set_pool); sync_pool_destruct(metadata->objects_pool_before_gc); sync_pool_destruct(metadata->objects_pool_after_gc); sync_pool_destruct(metadata->resurrect_objects_pool_before_gc); sync_pool_destruct(metadata->resurrect_objects_pool_after_gc); sync_pool_destruct(metadata->new_objects_pool); sync_pool_destruct(metadata->hashcode_pool_before_gc); sync_pool_destruct(metadata->hashcode_pool_after_gc); sync_pool_destruct(metadata->obj_with_fin_pool); sync_pool_destruct(metadata->finalizable_obj_pool); for(unsigned int i=0; i<metadata->num_alloc_segs; i++){ assert(metadata->segments[i]); STD_FREE(metadata->segments[i]); } STD_FREE( heap_verifier->heap_verifier_metadata); heap_verifier->heap_verifier_metadata = NULL; }
void compile_clear_dynamic_code_list(DynamicCode* list) { while (list) { DynamicCode* next = list->next; if (list->free_name) STD_FREE((void *)list->name); STD_FREE(list); list = next; } }
ivm_char_t * ivm_file_readAll(ivm_file_t *file, ivm_size_t *size) { ivm_file_raw_t fp = file->fp; ivm_size_t len = ivm_file_length(file), tmp_len; ivm_size_t orig = IVM_FTELL(fp); ivm_char_t *ret, *cur; if (len == -1) { // read from non-static file len = IVM_DEFAULT_FILE_READ_BUFFER_SIZE; cur = ret = STD_ALLOC(sizeof(*ret) * (len + 1)); // read and check if the buffer is full while ((tmp_len = IVM_FREAD(cur, sizeof(*cur), IVM_DEFAULT_FILE_READ_BUFFER_SIZE, fp)) == IVM_DEFAULT_FILE_READ_BUFFER_SIZE) { len += IVM_DEFAULT_FILE_READ_BUFFER_SIZE; ret = STD_REALLOC(ret, sizeof(*ret) * (len + 1)); cur = ret + len - IVM_DEFAULT_FILE_READ_BUFFER_SIZE; // next write point } if (!feof(fp)) { STD_FREE(ret); return IVM_NULL; } // trim the empty buffer len -= IVM_DEFAULT_FILE_READ_BUFFER_SIZE - tmp_len; ret = STD_REALLOC(ret, sizeof(*ret) * (len + 1)); } else { len -= IVM_FTELL(fp); // remove the length we've already read ret = STD_ALLOC(sizeof(*ret) * (len + 1)); // FGOTO(fp, HEAD); if (len != IVM_FREAD(ret, sizeof(*ret), len, fp)) { /* unexpected read len */ // unwind to the original position IVM_FSEEK(fp, IVM_FSEEK_HEAD, orig); STD_FREE(ret); return IVM_NULL; } } ret[len] = '\0'; if (size) *size = len; // return size return ret; }
int port_thread_detach() { port_tls_data_t* tlsdata; int res; if (!port_shared_data && (res = init_port_shared_data()) != 0) return res; tlsdata = get_private_tls_data(); if (!tlsdata) return 0; if (port_thread_detach_temporary() == 0) return 0; res = set_guard_page(tlsdata, FALSE); if (res != 0) return res; size_t mapping_addr = (size_t)tlsdata->stack_addr - tlsdata->stack_size; size_t mapping_size = (tlsdata->guard_stack_size + tlsdata->mem_protect_size + 2*PSD->guard_page_size - 1) & ~(PSD->guard_page_size - 1); munmap((void*)mapping_addr, mapping_size); if (tlsdata->foreign) STD_FREE(tlsdata); return set_private_tls_data(NULL); }
static void c_handler(Registers* pregs, void* fault_addr, size_t code, size_t flags) { // this exception handler is executed *after* VEH handler returned int result; Boolean iscrash = (DWORD)flags == EXCEPTION_NONCONTINUABLE; switch ((DWORD)code) { case STATUS_STACK_OVERFLOW: result = port_process_signal(PORT_SIGNAL_STACK_OVERFLOW, pregs, fault_addr, iscrash); break; case STATUS_ACCESS_VIOLATION: result = port_process_signal(PORT_SIGNAL_GPF, pregs, fault_addr, iscrash); break; case STATUS_INTEGER_DIVIDE_BY_ZERO: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_INT_OVERFLOW: result = port_process_signal(PORT_SIGNAL_ARITHMETIC, pregs, fault_addr, iscrash); break; case JVMTI_EXCEPTION_STATUS: result = port_process_signal(PORT_SIGNAL_BREAKPOINT, pregs, fault_addr, iscrash); break; default: result = port_process_signal(PORT_SIGNAL_UNKNOWN, pregs, fault_addr, TRUE); } port_tls_data_t* tlsdata = get_private_tls_data(); if (result == 0) { // Restore guard page if needed if (tlsdata->restore_guard_page) { port_thread_restore_guard_page(); tlsdata->restore_guard_page = FALSE; } if (port_thread_detach_temporary() == 0) STD_FREE(tlsdata); return; } if (result > 0 /*Assert dialog*/|| FLAG_CORE) { // Prepare second catch of this exception to produce minidump (because // we've lost LPEXCEPTION_POINTERS structure) and/or show assert dialog if (FLAG_CORE) tlsdata->produce_core = TRUE; if (result > 0) tlsdata->debugger = TRUE; // To catch STACK_OVERFLOW port_thread_restore_guard_page(); return; // To produce exception again } _exit(-1); // We need neither dump nor assert dialog }
IVM_PRIVATE void _ivm_buffer_stream_destruct(ivm_stream_t *stream) { ivm_buffer_stream_t *bufs = (ivm_buffer_stream_t *)stream; STD_FREE(bufs->buf); return; }
void ivm_file_free_n(ivm_file_t *file) { if (file) { STD_FREE(file); } return; }
void ivm_file_free(ivm_file_t *file) { if (file) { IVM_FCLOSE(file->fp); STD_FREE(file); } return; }
void mutator_destruct(GC* gc, void *unused_gc_information) { Mutator *mutator = (Mutator *)gc_get_tls(); alloc_context_reset((Allocator*)mutator); lock(gc->mutator_list_lock); // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #ifdef USE_UNIQUE_MARK_SWEEP_GC allocactor_destruct_local_chunks((Allocator*)mutator); #endif mutator_register_new_obj_size(mutator); volatile Mutator *temp = gc->mutator_list; if (temp == mutator) { /* it is at the head of the list */ gc->mutator_list = temp->next; } else { while (temp->next != mutator) { temp = temp->next; assert(temp); } temp->next = mutator->next; } gc->num_mutators--; unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ if(gc_is_gen_mode()){ /* put back the remset when a mutator exits */ pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set); mutator->rem_set = NULL; } if(mutator->obj_with_fin){ pool_put_entry(gc->finref_metadata->obj_with_fin_pool, mutator->obj_with_fin); mutator->obj_with_fin = NULL; } lock(mutator->dirty_set_lock); if( mutator->dirty_set != NULL){ if(vector_block_is_empty(mutator->dirty_set)) pool_put_entry(gc->metadata->free_set_pool, mutator->dirty_set); else{ /* FIXME:: this condition may be released. */ pool_put_entry(gc->metadata->gc_dirty_set_pool, mutator->dirty_set); mutator->dirty_set = NULL; } } unlock(mutator->dirty_set_lock); STD_FREE(mutator); gc_set_tls(NULL); return; }
void ivm_stream_free(ivm_stream_t *stream) { if (stream) { if (stream->des) { stream->des(stream); } STD_FREE(stream); } return; }
APR_DECLARE(apr_status_t) port_dso_load_ex(apr_dso_handle_t** handle, const char* path, U_32 mode, apr_pool_t* pool){ /* * FIXME Windows does not support lazy dll resolution a la Linux's RTLD_LAZY. * Proper support for it requires hacking of APR DSO functions. * Just ignore the <code>mode<code> param for now. */ /*if (mode == PORT_DSO_DEFAULT || !path) {*/ char *self_path; apr_status_t res; if (!path) { port_executable_name(&self_path); res = apr_dso_load(handle, (const char*)self_path, pool); STD_FREE(self_path); return res; } return apr_dso_load(handle, path, pool); /*} else { HINSTANCE native_handle = NULL; DWORD flag = (mode & PORT_DSO_BIND_DEFER) ? (DONT_RESOLVE_DLL_REFERENCES) : (0); char *cp = apr_pstrdup(pool, path); char *p = cp; while ((p = strchr(p, '/')) != NULL) { *p = '\\'; } native_handle = LoadLibraryEx(cp, NULL, flag); *handle = apr_palloc(pool, sizeof(apr_dso_handle_t)); if (native_handle == 0) { native_handle = LoadLibraryEx(cp, NULL, flag | LOAD_WITH_ALTERED_SEARCH_PATH); if (native_handle == 0) { DWORD sys_err = apr_get_os_error(); (*handle)->error = sys_err; return sys_err; } } (*handle)->handle = native_handle; (*handle)->pool = pool; (*handle)->error = APR_SUCCESS; return APR_SUCCESS; }*/ }
void Method::unregister_jit_recompiled_method_callbacks(const Method* caller) { TRACE2("cu.debug", "unregister jit callback, caller=" << caller << " callee=" << this); Method_Change_Notification_Record *nr,*prev = NULL; for (nr = _notify_recompiled_records; nr != NULL; ) { if (nr->caller == caller) { if (prev) { prev->next = nr->next; } else { _notify_recompiled_records = nr->next; } Method_Change_Notification_Record *next = nr->next; STD_FREE(nr); nr = next; } else { prev = nr; nr = nr->next; } } }
// This function is for native library support // It takes a class name with .s not /s. // FIXME: caller could convert it itself Class_Handle class_find_loaded(Class_Loader_Handle loader, const char* name) { char* name3 = strdup(name); char* p = name3; while (*p) { if (*p=='.') *p='/'; p++; } Global_Env* env = VM_Global_State::loader_env; String* name2 = env->string_pool.lookup(name3); Class* ch; if (loader) { ch = loader->LookupClass(name2); } else { ch = env->bootstrap_class_loader->LookupClass(name2); } STD_FREE(name3); if(ch && (!ch->verify(env) || !ch->prepare(env))) return NULL; return ch; }
ivm_char_t * ivm_file_read_n(ivm_file_t *file, ivm_size_t len) { ivm_file_raw_t fp = file->fp; ivm_size_t orig = IVM_FTELL(fp); ivm_char_t *ret; ret = STD_ALLOC(sizeof(*ret) * (len + 1)); // IVM_TRACE("%ld\n", len); if (len != IVM_FREAD(ret, sizeof(*ret), len, fp)) { /* unexpected read len */ IVM_FSEEK(fp, IVM_FSEEK_HEAD, orig); STD_FREE(ret); return IVM_NULL; } ret[len] = '\0'; return ret; }
/*Copy the fake blocks into real blocks, reconnect these new block into main list of mspace. *Free the fake blocks. The infomation of mspace is not updated yet. */ void gc_space_tuner_release_fake_blocks_for_los_shrink(GC* gc) { Space_Tuner *tuner = gc->tuner; Blocked_Space* mspace = (Blocked_Space*)gc_get_mos((GC_Gen*)gc); POINTER_SIZE_INT tune_size = tuner->tuning_size; unsigned int tune_blocks = (unsigned int)(tune_size >> GC_BLOCK_SHIFT_COUNT); Block* blocks = (Block*)((POINTER_SIZE_INT)mspace->blocks - tune_size); Block_Header* last_real_block = (Block_Header*)blocks; unsigned int i; for(i=0; i < tune_blocks; i++){ Block_Header* real_block = (Block_Header*)&(blocks[i]); Block_Header* fake_block = &tuner->interim_blocks[i]; memcpy((void*)real_block, (void*)fake_block, sizeof(Block_Header)); last_real_block->next = real_block; last_real_block = real_block; } last_real_block->next = (Block_Header*)mspace->blocks; STD_FREE(tuner->interim_blocks); return; }
// Create an exception from a given type and a message. // Set cause to the current thread exception. static void compile_raise_exception(const char* name, const char* message, Method* method) { assert(hythread_is_suspend_enabled()); jthrowable old_exc = exn_get(); exn_clear(); const char* c = method->get_class()->get_name()->bytes; const char* m = method->get_name()->bytes; const char* d = method->get_descriptor()->bytes; size_t sz = 3 + // a space, a dot, and a terminator strlen(message) + method->get_class()->get_name()->len + method->get_name()->len + method->get_descriptor()->len; char* msg_raw = (char*)STD_MALLOC(sz); assert(msg_raw); sprintf(msg_raw, "%s%s.%s%s", message, c, m, d); assert(strlen(msg_raw) < sz); jthrowable new_exc = exn_create(name, msg_raw, old_exc); exn_raise_object(new_exc); STD_FREE(msg_raw); }
int port_thread_attach() { int res; port_tls_data_t* tlsdata; if (!port_shared_data && (res = init_port_shared_data()) != 0) return res; if (get_private_tls_data()) return 0; tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t)); if (!tlsdata) return ENOMEM; res = port_thread_attach_local(tlsdata, FALSE, TRUE, 0); if (res != 0) STD_FREE(tlsdata); return res; }
Class_Handle class_find_class_from_loader(Class_Loader_Handle loader, const char* n, Boolean init) { ASSERT_RAISE_AREA; assert(hythread_is_suspend_enabled()); // -salikh char *new_name = strdup(n); char *p = new_name; while (*p) { if (*p == '.') *p = '/'; p++; } String* name = VM_Global_State::loader_env->string_pool.lookup(new_name); STD_FREE(new_name); Class* ch; if (loader) { ch = class_load_verify_prepare_by_loader_jni( VM_Global_State::loader_env, name, loader); } else { assert(hythread_is_suspend_enabled()); ch = class_load_verify_prepare_from_jni(VM_Global_State::loader_env, name); } if (!ch) return NULL; // All initialization from jni should not propagate exceptions and // should return to calling native method. if(init) { class_initialize_from_jni(ch); if (exn_raised()) { return NULL; } } if(exn_raised()) { return 0; } return ch; }
Class* resolve_class_array_of_class(Global_Env* env, Class* cc) { // If the element type is primitive, return one of the preloaded // classes of arrays of primitive types. if (cc->is_primitive()) { if (cc == env->Boolean_Class) { return env->ArrayOfBoolean_Class; } else if (cc == env->Byte_Class) { return env->ArrayOfByte_Class; } else if (cc == env->Char_Class) { return env->ArrayOfChar_Class; } else if (cc == env->Short_Class) { return env->ArrayOfShort_Class; } else if (cc == env->Int_Class) { return env->ArrayOfInt_Class; } else if (cc == env->Long_Class) { return env->ArrayOfLong_Class; } else if (cc == env->Float_Class) { return env->ArrayOfFloat_Class; } else if (cc == env->Double_Class) { return env->ArrayOfDouble_Class; } } char *array_name = (char *)STD_MALLOC(cc->get_name()->len + 5); if(cc->get_name()->bytes[0] == '[') { sprintf(array_name, "[%s", cc->get_name()->bytes); } else { sprintf(array_name, "[L%s;", cc->get_name()->bytes); } String *arr_str = env->string_pool.lookup(array_name); STD_FREE(array_name); Class* arr_clss = cc->get_class_loader()->LoadVerifyAndPrepareClass(env, arr_str); return arr_clss; } // resolve_class_array_of_class
static PORT_CDECL int thread_start_func(void* arg) { int err, result; port_tls_data_t* tlsdata = NULL; thread_start_struct_t* ptr = (thread_start_struct_t*)arg; port_threadfunc_t fun = ptr->fun; size_t stack_size = ptr->stack_size; arg = ptr->arg; STD_FREE(ptr); if (port_shared_data) { tlsdata = (port_tls_data_t*)STD_ALLOCA(sizeof(port_tls_data_t)); err = port_thread_attach_local(tlsdata, FALSE, FALSE, stack_size); assert(err == 0); } result = fun(arg); if (tlsdata) port_thread_detach(); return result; }
void gc_gen_collector_stats_destruct(Collector* collector) { STD_FREE(collector->stats); }
static void c_handler(Registers* pregs, size_t signum, void* fault_addr) { // this exception handler is executed *after* OS signal handler returned int result; port_tls_data_t* tlsdata = get_private_tls_data(); switch ((int)signum) { case SIGSEGV: if (tlsdata->restore_guard_page) { // Now it's safe to disable alternative stack set_alt_stack(tlsdata, FALSE); result = port_process_signal(PORT_SIGNAL_STACK_OVERFLOW, pregs, fault_addr, FALSE); } else result = port_process_signal(PORT_SIGNAL_GPF, pregs, fault_addr, FALSE); break; case SIGFPE: result = port_process_signal(PORT_SIGNAL_ARITHMETIC, pregs, fault_addr, FALSE); break; case SIGTRAP: // Correct return address pregs->set_ip((void*)((POINTER_SIZE_INT)pregs->get_ip() - 1)); result = port_process_signal(PORT_SIGNAL_BREAKPOINT, pregs, fault_addr, FALSE); break; case SIGINT: result = port_process_signal(PORT_SIGNAL_CTRL_C, pregs, fault_addr, FALSE); break; case SIGQUIT: result = port_process_signal(PORT_SIGNAL_QUIT, pregs, fault_addr, FALSE); break; case SIGABRT: result = port_process_signal(PORT_SIGNAL_ABORT, NULL, fault_addr, FALSE); break; default: result = port_process_signal(PORT_SIGNAL_UNKNOWN, pregs, fault_addr, TRUE); } if (result == 0) { // Restore guard page if needed if (tlsdata->restore_guard_page) { port_thread_restore_guard_page(); tlsdata->restore_guard_page = FALSE; if (port_thread_detach_temporary() == 0) STD_FREE(tlsdata); } return; } // We've got a crash if (signum == SIGSEGV) { port_thread_restore_guard_page(); // To catch SO again tlsdata->restore_guard_page = FALSE; } if (result > 0) // invoke debugger { // Prepare second catch of signal to attach GDB from signal handler //assert(tlsdata); // Should be attached - provided by general_signal_handler tlsdata->debugger = TRUE; return; // To produce signal again } // result < 0 - exit process if (FLAG_CORE) { // Return to the same place to produce the same crash and generate core signal(signum, SIG_DFL); // setup default handler return; } // No core needed - simply terminate _exit(-1); }
ncaiError JNICALL ncaiWriteMemory(ncaiEnv* env, void* addr, size_t size, void* buf) { TRACE2("ncai.memory", "WriteMemory called"); if (!env) return NCAI_ERROR_INVALID_ENVIRONMENT; VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt; LMAutoUnlock lock(vm_breaks->get_lock()); jbyte* end_addr = (jbyte*)addr + size; VMBreakPoint* cur; size_t rewrite_count = 0; // Count addresses in given range for (cur = vm_breaks->get_first_breakpoint(); cur; cur = vm_breaks->get_next_breakpoint(cur)) { if (cur->addr >= addr && cur->addr < end_addr) ++rewrite_count; } // Simple case: there are no breakpoints in specified address range if (rewrite_count == 0) { if (port_write_memory(addr, size, buf) == 0) return NCAI_ERROR_NONE; else return NCAI_ERROR_ACCESS_DENIED; } // Allocate array for address sorting RewriteArray rwa; rwa.array = (BreakListItem*)STD_MALLOC(rewrite_count*sizeof(BreakListItem)); if (!rwa.array) return NCAI_ERROR_OUT_OF_MEMORY; memset(rwa.array, 0, rewrite_count*sizeof(BreakListItem)); rwa.list = NULL; rwa.size = rewrite_count; rwa.count = 0; // Add matching addresses to sorted list for (cur = vm_breaks->get_first_breakpoint(); cur; cur = vm_breaks->get_next_breakpoint(cur)) { if (cur->addr >= addr && cur->addr < end_addr) add_rewrite_address(&rwa, cur); } // Write memory size_t remain = size; BreakListItem* cur_bla = rwa.list; assert(cur_bla); jbyte* cbuf = (jbyte*)buf; jbyte* cur_addr = (jbyte*)addr; int err = 0; while (remain) { if (!cur_bla || cur_bla->bp->addr > cur_addr) { // Write buffer to memory size_t offset = (size_t)cur_addr - (size_t)addr; size_t chunk_size = cur_bla ? ((jbyte*)cur_bla->bp->addr - cur_addr) : (end_addr - cur_addr); err = port_write_memory(cur_addr, chunk_size, cbuf + offset); if (err != 0) break; cur_addr += chunk_size; remain -= chunk_size; } if (cur_bla) { // Write byte from buffer to 'saved_byte' field in breakpoint assert(cur_addr == cur_bla->bp->addr); size_t offset = (size_t)cur_addr - (size_t)addr; cur_bla->bp->saved_byte = cbuf[offset]; cur_bla = cur_bla->next; ++cur_addr; --remain; } } STD_FREE(rwa.array); return (err == 0) ? NCAI_ERROR_NONE : NCAI_ERROR_ACCESS_DENIED; }
void parse_vm_arguments2(Global_Env *p_env) { bool version_printed = false; #ifdef _DEBUG TRACE("p_env->vm_arguments.nOptions = " << p_env->vm_arguments.nOptions); for (int _i = 0; _i < p_env->vm_arguments.nOptions; _i++) TRACE("p_env->vm_arguments.options[ " << _i << "] = " << p_env->vm_arguments.options[_i].optionString); #endif //_DEBUG apr_pool_t *pool; apr_pool_create(&pool, 0); for (int i = 0; i < p_env->vm_arguments.nOptions; i++) { const char* option = p_env->vm_arguments.options[i].optionString; if (begins_with(option, XBOOTCLASSPATH)) { /* * Override for bootclasspath - * set in the environment- the boot classloader will be responsible for * processing and setting up "vm.boot.class.path" and "sun.boot.class.path" * Note that in the case of multiple arguments, the last one will be used */ p_env->VmProperties()->set(XBOOTCLASSPATH, option + strlen(XBOOTCLASSPATH)); } else if (begins_with(option, XBOOTCLASSPATH_A)) { /* * addition to append to boot classpath * set in environment - responsibility of boot classloader to process * Note that we accumulate if multiple, appending each time */ char *bcp_old = p_env->VmProperties()->get(XBOOTCLASSPATH_A); const char *value = option + strlen(XBOOTCLASSPATH_A); char *bcp_new = NULL; if (bcp_old) { char *tmp = (char *) STD_MALLOC(strlen(bcp_old) + strlen(PORT_PATH_SEPARATOR_STR) + strlen(value) + 1); strcpy(tmp, bcp_old); strcat(tmp, PORT_PATH_SEPARATOR_STR); strcat(tmp, value); bcp_new = tmp; } p_env->VmProperties()->set(XBOOTCLASSPATH_A, bcp_old ? bcp_new : value); p_env->VmProperties()->destroy(bcp_old); STD_FREE((void*)bcp_new); } else if (begins_with(option, XBOOTCLASSPATH_P)) { /* * addition to prepend to boot classpath * set in environment - responsibility of boot classloader to process * Note that we accumulate if multiple, prepending each time */ char *bcp_old = p_env->VmProperties()->get(XBOOTCLASSPATH_P); const char *value = option + strlen(XBOOTCLASSPATH_P); char *bcp_new = NULL; if (bcp_old) { char *tmp = (char *) STD_MALLOC(strlen(bcp_old) + strlen(PORT_PATH_SEPARATOR_STR) + strlen(value) + 1); strcpy(tmp, value); strcat(tmp, PORT_PATH_SEPARATOR_STR); strcat(tmp, bcp_old); bcp_new = tmp; } p_env->VmProperties()->set(XBOOTCLASSPATH_P, bcp_old ? bcp_new : value); p_env->VmProperties()->destroy(bcp_old); STD_FREE((void*)bcp_new); } else if (begins_with(option, "-Xjit:")) { // Do nothing here, just skip this option for later parsing } else if (strcmp(option, "-Xint") == 0) { p_env->VmProperties()->set("vm.use_interpreter", "true"); #ifdef VM_STATS } else if (begins_with(option, "-Xstats:")) { vm_print_total_stats = true; const char* arg = option + strlen("-Xstats:"); vm_print_total_stats_level = atoi(arg); #endif } else if (strcmp(option, "-version") == 0) { // Print the version number and exit LECHO_VERSION; log_exit(0); } else if (strcmp(option, "-showversion") == 0) { if (!version_printed) { // Print the version number and continue LECHO_VERSION; version_printed = true; } } else if (strcmp(option, "-fullversion") == 0) { // Print the version number and exit LECHO_VM_VERSION; log_exit(0); } else if (begins_with(option, "-Xgc:")) { // make prop_key to be "gc.<something>" char* prop_key = strdup(option + strlen("-X")); prop_key[2] = '.'; TRACE(prop_key << " = 1"); p_env->VmProperties()->set(prop_key, "1"); free(prop_key); } else if (begins_with(option, "-Xem:")) { const char* arg = option + strlen("-Xem:"); p_env->VmProperties()->set("em.properties", arg); } else if (strcmp(option, "-client") == 0 || strcmp(option, "-server") == 0) { p_env->VmProperties()->set("em.properties", option + 1); } else if (begins_with(option, "-Xms") || begins_with(option, "-ms")) { // cut -Xms || -ms const char* arg = option + (begins_with(option, "-ms") ? 3 : 4); TRACE("gc.ms = " << arg); if (atoi(arg) <= 0) { LECHO(34, "Negative or invalid heap size. Default value will be used!"); } p_env->VmProperties()->set("gc.ms", arg); } else if (begins_with(option, "-Xmx") || begins_with(option, "-mx")) { // cut -Xmx const char* arg = option + (begins_with(option, "-mx") ? 3 : 4); TRACE("gc.mx = " << arg); if (atoi(arg) <= 0) { LECHO(34, "Negative or invalid heap size. Default value will be used!"); } p_env->VmProperties()->set("gc.mx", arg); } else if (begins_with(option, "-Xss")) { const char* arg = option + 4; TRACE("thread.stacksize = " << arg); if (atoi(arg) <= 0) { LECHO(34, "Negative or invalid stack size. Default value will be used!"); } p_env->VmProperties()->set("thread.stacksize", arg); } else if (begins_with(option, STRING_POOL_SIZE_OPTION)) { // the pool is already created } else if (begins_with(option, "-agentlib:")) { p_env->TI->addAgent(option); } else if (begins_with(option, "-agentpath:")) { p_env->TI->addAgent(option); } else if (begins_with(option, "-javaagent:")) { char* dest = (char*) STD_MALLOC(strlen("-agentlib:hyinstrument=") + strlen(option + 11) + 1); strcpy(dest, "-agentlib:hyinstrument="); strcat(dest, option + 11); p_env->TI->addAgent(dest); STD_FREE((void*) dest); } else if (begins_with(option, "-Xrun")) { // Compatibility with JNDI p_env->TI->addAgent(option); } else if (strcmp(option, "-Xnoagent") == 0) { // Do nothing, this option is only for compatibility with old JREs } else if (strcmp(option, "-Xdebug") == 0) { // Do nothing, this option is only for compatibility with old JREs } else if (strcmp(option, "-Xfuture") == 0) { // Do nothing, this option is only for compatibility with old JREs } else if (strcmp(option, "-Xinvisible") == 0) { p_env->retain_invisible_annotations = true; } else if (strcmp(option, "-Xverify") == 0) { p_env->verify_all = true; } else if (strcmp(option, "-Xverify:none") == 0 || strcmp(option, "-noverify") == 0) { p_env->VmProperties()->set("vm.use_verifier", "false"); } else if (strcmp(option, "-Xverify:all") == 0) { p_env->verify_all = true; p_env->verify_strict = true; } else if (strcmp(option, "-Xverify:strict") == 0) { p_env->verify_all = true; p_env->verify_strict = true; } else if (strcmp(option, "-verify") == 0) { p_env->verify_all = true; } else if (begins_with(option, "-verbose")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xfileline")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xthread")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xcategory")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xtimestamp")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xverbose")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xwarn")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xfunction")) { // Moved to set_log_levels_from_cmd #ifdef _DEBUG } else if (begins_with(option, "-Xlog")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xtrace")) { // Moved to set_log_levels_from_cmd #endif //_DEBUG } else if (strncmp(option, "-D", 2) == 0) { } else if (strncmp(option, "-XD", 3) == 0 || strncmp(option, "-XX:", 4) == 0) { } else if (strcmp(option, "-Xdumpstubs") == 0) { dump_stubs = true; } else if (strcmp(option, "-Xparallel_jit") == 0) { parallel_jit = true; } else if (strcmp(option, "-Xno_parallel_jit") == 0) { parallel_jit = false; } else if (begins_with(option, "-Xdumpfile:")) { const char* arg = option + strlen("-Xdumpfile:"); dump_file_name = arg; } else if (strcmp(option, "_org.apache.harmony.vmi.portlib") == 0) { // Store a pointer to the portlib p_env->portLib = p_env->vm_arguments.options[i].extraInfo; } else if (strcmp(option, "-help") == 0 || strcmp(option, "-h") == 0 || strcmp(option, "-?") == 0) { print_generic_help(); log_exit(0); } else if (strcmp(option,"-X") == 0) { print_help_on_nonstandard_options(); log_exit(0); } else if (begins_with(option, "-enableassertions")) { add_assert_rec(p_env, option, "-enableassertions", true); } else if (begins_with(option, "-ea")) { add_assert_rec(p_env, option, "-ea", true); } else if (begins_with(option, "-disableassertions")) { add_assert_rec(p_env, option, "-disableassertions", false); } else if (begins_with(option, "-da")) { add_assert_rec(p_env, option, "-da", false); } else if (strcmp(option, "-esa") == 0 || strcmp(option, "-enablesystemassertions") == 0) { get_assert_reg(p_env)->enable_system = true; } else if (strcmp(option, "-dsa") == 0 || strcmp(option, "-disablesystemassertions") == 0) { if (p_env->assert_reg) { p_env->assert_reg->enable_system = false; } } else { LECHO(30, "Unknown option {0}" << option); USE_JAVA_HELP; log_exit(1); } } // for apr_pool_destroy(pool); } //parse_vm_arguments2
LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception) { DWORD code = nt_exception->ExceptionRecord->ExceptionCode; void* fault_addr = nt_exception->ExceptionRecord->ExceptionAddress; Registers regs; // Convert NT context to Registers port_thread_context_to_regs(®s, nt_exception->ContextRecord); // Check if TLS structure is set - probably we should produce minidump port_tls_data_t* tlsdata = get_private_tls_data(); if (!tlsdata) // Tread is not attached - attach thread temporarily { int res; tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t)); if (tlsdata) // Try to attach the thread res = port_thread_attach_local(tlsdata, TRUE, TRUE, 0); if (!tlsdata || res != 0) { // Can't process correctly; perform default actions if (FLAG_CORE) create_minidump(nt_exception); if (FLAG_DBG) { show_debugger_dialog(); // Workaround; EXCEPTION_CONTINUE_SEARCH does not work _exit(-1); return EXCEPTION_CONTINUE_SEARCH; // Assert dialog } _exit(-1); } // SO for alien thread can't be processed out of VEH if (code == STATUS_STACK_OVERFLOW && sd_is_handler_registered(PORT_SIGNAL_STACK_OVERFLOW)) { int result; size_t alt_stack_size = ALT_PAGES_COUNT*tlsdata->guard_page_size; void* alt_stack = map_alt_stack(alt_stack_size); void* stack_bottom = (void*)((POINTER_SIZE_INT)alt_stack + alt_stack_size); if (alt_stack) result = (int)(POINTER_SIZE_INT)port_call_alt_stack( port_process_signal, stack_bottom, 4, PORT_SIGNAL_STACK_OVERFLOW, ®s, fault_addr, FALSE); else result = port_process_signal(PORT_SIGNAL_STACK_OVERFLOW, ®s, fault_addr, FALSE); if (result == 0) { if (port_thread_detach_temporary() == 0) STD_FREE(tlsdata); if (alt_stack) unmap_alt_stack(alt_stack, alt_stack_size); return EXCEPTION_CONTINUE_EXECUTION; } if (FLAG_CORE) { if (alt_stack) port_call_alt_stack(create_minidump, stack_bottom, 1, nt_exception); else create_minidump(nt_exception); } if (alt_stack) unmap_alt_stack(alt_stack, alt_stack_size); if (result > 0) { show_debugger_dialog(); // Workaround; EXCEPTION_CONTINUE_SEARCH does not work _exit(-1); shutdown_signals(); return EXCEPTION_CONTINUE_SEARCH; // Assert dialog } _exit(-1); } } if (tlsdata->produce_core) { create_minidump(nt_exception); if (!tlsdata->debugger) _exit(-1); } if (tlsdata->debugger) { show_debugger_dialog(); // Workaround _exit(-1); // Go to handler to restore CRT/VEH settings and crash once again // port_set_longjump_regs(&prepare_assert_dialog, ®s, 1, ®s); // port_thread_regs_to_context(nt_exception->ContextRecord, ®s); // return EXCEPTION_CONTINUE_EXECUTION; } switch (code) { case STATUS_STACK_OVERFLOW: if (!sd_is_handler_registered(PORT_SIGNAL_STACK_OVERFLOW)) return EXCEPTION_CONTINUE_SEARCH; break; case STATUS_ACCESS_VIOLATION: if (!sd_is_handler_registered(PORT_SIGNAL_GPF)) return EXCEPTION_CONTINUE_SEARCH; break; case JVMTI_EXCEPTION_STATUS: if (!sd_is_handler_registered(PORT_SIGNAL_BREAKPOINT)) return EXCEPTION_CONTINUE_SEARCH; break; case STATUS_INTEGER_DIVIDE_BY_ZERO: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_INT_OVERFLOW: if (!sd_is_handler_registered(PORT_SIGNAL_ARITHMETIC)) return EXCEPTION_CONTINUE_SEARCH; break; default: return EXCEPTION_CONTINUE_SEARCH; } if (code == STATUS_STACK_OVERFLOW) { tlsdata->guard_page_set = FALSE; // GUARD_PAGE was cleared by OS if (!tlsdata->restore_guard_page) tlsdata->restore_guard_page = TRUE; } // Prepare to transfering control out of VEH handler port_set_longjump_regs(&c_handler, ®s, 4, ®s, nt_exception->ExceptionRecord->ExceptionAddress, (void*)(size_t)nt_exception->ExceptionRecord->ExceptionCode, (void*)(size_t)nt_exception->ExceptionRecord->ExceptionFlags); // Convert prepared Registers back to NT context port_thread_regs_to_context(nt_exception->ContextRecord, ®s); // Return from VEH - presumably continue execution return EXCEPTION_CONTINUE_EXECUTION; }
int port_thread_create(/* out */osthread_t* phandle, size_t stacksize, int priority, port_threadfunc_t func, void *data) { pthread_t thread; pthread_attr_t attr; pthread_attr_t attr_nosched; struct sched_param param; thread_start_struct_t* startstr; int res; if (!port_shared_data) { res = init_port_shared_data(); /* assert(res); */ /* It's OK to have an error here when Port shared library is not available yet; only signals/crash handling will not be available for the thread */ /* return res; */ } if (!func) return EINVAL; startstr = (thread_start_struct_t*)STD_MALLOC(sizeof(thread_start_struct_t)); if (!startstr) return ENOMEM; pthread_attr_init(&attr); pthread_attr_init(&attr_nosched); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr_nosched, PTHREAD_CREATE_DETACHED); if (stacksize != 0) { if (stacksize < MINSIGSTKSZ) stacksize = MINSIGSTKSZ; if (port_shared_data) { size_t min_stacksize = /* Let's get alt stack size for normal stack and add guard page size */ ((2*port_shared_data->guard_stack_size + port_shared_data->guard_page_size) /* Roung up to alt stack size */ + port_shared_data->guard_stack_size - 1) & ~(port_shared_data->guard_stack_size - 1); if (stacksize < min_stacksize) stacksize = min_stacksize; } res = pthread_attr_setstacksize(&attr, stacksize); if (res == 0) res = pthread_attr_setstacksize(&attr_nosched, stacksize); if (res) { pthread_attr_destroy(&attr); pthread_attr_destroy(&attr_nosched); STD_FREE(startstr); return res; } } if (priority) { res = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if (res == 0) { param.sched_priority = priority; res = pthread_attr_setschedparam(&attr, ¶m); } /* This does not work anyway on some Linuses if (res != 0) { pthread_attr_destroy(&attr); pthread_attr_destroy(&attr_nosched); STD_FREE(startstr); return res; }*/ } startstr->fun = func; startstr->arg = data; startstr->stack_size = stacksize; res = pthread_create(&thread, &attr, (pthread_func_t)thread_start_func, startstr); if (res == EPERM) // EPERM relates to scheduling only res = pthread_create(&thread, &attr_nosched, (pthread_func_t)thread_start_func, startstr); pthread_attr_destroy(&attr); pthread_attr_destroy(&attr_nosched); if (res == 0) { *phandle = thread; return 0; } STD_FREE(startstr); return res; }
static void general_signal_handler(int signum, siginfo_t* info, void* context) { Registers regs; if (!context) return; // Convert OS context to Registers port_thread_context_to_regs(®s, (ucontext_t*)context); void* fault_addr = info ? info->si_addr : NULL; // Check if SIGSEGV is produced by port_read/write_memory port_tls_data_t* tlsdata = get_private_tls_data(); if (tlsdata && tlsdata->violation_flag) { tlsdata->violation_flag = 0; regs.set_ip(tlsdata->restart_address); return; } if (!tlsdata) // Tread is not attached - attach thread temporarily { int res; tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t)); if (tlsdata) // Try to attach the thread res = port_thread_attach_local(tlsdata, TRUE, TRUE, 0); if (!tlsdata || res != 0) { // Can't process correctly; perform default actions if (FLAG_DBG) { bool result = gdb_crash_handler(®s); _exit(-1); // Exit process if not sucessful... } if (FLAG_CORE && signum != SIGABRT) // SIGABRT can't be rethrown { signal(signum, SIG_DFL); // setup default handler return; } _exit(-1); } // SIGSEGV can represent SO which can't be processed out of signal handler if (signum == SIGSEGV && // This can occur only when a user set an alternative stack is_stack_overflow(tlsdata, fault_addr)) { int result = port_process_signal(PORT_SIGNAL_STACK_OVERFLOW, ®s, fault_addr, FALSE); if (result == 0) { if (port_thread_detach_temporary() == 0) STD_FREE(tlsdata); return; } if (result > 0) tlsdata->debugger = TRUE; else { if (FLAG_CORE) { // Rethrow crash to generate core signal(signum, SIG_DFL); // setup default handler return; } _exit(-1); } } } if (tlsdata->debugger) { bool result = gdb_crash_handler(®s); _exit(-1); // Exit process if not sucessful... } if (signum == SIGABRT && // SIGABRT can't be trown again from c_handler FLAG_DBG) { // So attaching GDB right here bool result = gdb_crash_handler(®s); _exit(-1); // Exit process if not sucessful... } if (signum == SIGSEGV && is_stack_overflow(tlsdata, fault_addr)) { // Second SO while previous SO is not processed yet - is GPF if (tlsdata->restore_guard_page) tlsdata->restore_guard_page = FALSE; else { // To process signal on protected stack area port_thread_clear_guard_page(); // Note: the call above does not disable alternative stack // It can't be made while we are on alternative stack // Alt stack will be disabled explicitly in c_handler() tlsdata->restore_guard_page = TRUE; } } // Prepare registers for transfering control out of signal handler void* callback = (void*)&c_handler; port_set_longjump_regs(callback, ®s, 3, ®s, (void*)(size_t)signum, fault_addr); // Convert prepared Registers back to OS context port_thread_regs_to_context((ucontext_t*)context, ®s); // Return from signal handler to go to C handler }
void gc_gen_stats_destruct(GC_Gen* gc) { STD_FREE(gc->stats); }
/* * Class: java_lang_VMClassRegistry * Method: getSystemPackages * Signature: (I)[[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClassRegistry_getSystemPackages (JNIEnv *jenv, jclass, jint len) { Global_Env* genv = VM_Global_State::loader_env; ClassLoader* cl = static_cast<ClassLoader*> (genv->bootstrap_class_loader); Package_Table* ptab = cl->getPackageTable(); cl->Lock(); unsigned p_num = (unsigned)ptab->size(); if (p_num == (unsigned)len) { cl->Unlock(); return NULL; } const char ** pkgs = (const char **)STD_MALLOC(p_num * 2 * sizeof(char*)); size_t buf_len = 0; unsigned index = 0; for (Package_Table::const_iterator it = ptab->begin(), end = ptab->end(); it != end; ++it) { const char* name = pkgs[index++] = (*it).first->bytes; pkgs[index++] = (*it).second->get_jar(); size_t name_len = (*it).first->len; if (name_len > buf_len) { buf_len = name_len; } } cl->Unlock(); jclass string_class = struct_Class_to_java_lang_Class_Handle(genv->JavaLangString_Class); static Class* aos = genv->LoadCoreClass("[Ljava/lang/String;"); jclass string_array_class = struct_Class_to_java_lang_Class_Handle(aos); assert(string_class); assert(string_array_class); jobjectArray result = NewObjectArray(jenv, p_num, string_array_class, NULL); if (result) { char* buf = (char*)STD_MALLOC(buf_len + 1); p_num *= 2; for (index = 0; index < p_num; ) { jobjectArray pair = NewObjectArray(jenv, 2, string_class, NULL); if (!pair) { break; } SetObjectArrayElement(jenv, result, index/2, pair); char* name = strcpy(buf, pkgs[index++]); for (char* c = name; *c != '\0'; ++c) { if (*c == '/') { *c = '.'; } } jstring jname = NewStringUTF(jenv, name); if (!jname) { break; } SetObjectArrayElement(jenv, pair, 0, jname); const char * jar = pkgs[index++]; if (jar) { jstring js = NewStringUTF(jenv, jar); if (!js) break; SetObjectArrayElement(jenv, pair, 1, js); } } STD_FREE(buf); } STD_FREE(pkgs); assert(result || exn_raised()); return result; }