static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp) { #ifdef ERTS_ENABLE_LOCK_CHECK #ifdef ERTS_SMP if (c_p && c_p_locks) erts_proc_lc_chk_only_proc_main(c_p); else #endif erts_lc_check_exact(NULL, 0); #endif /* * Clear breakpoints if any */ if (modp->code != NULL && modp->code[MI_NUM_BREAKPOINTS] > 0) { if (c_p && c_p_locks) erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); erts_clear_module_break(modp); modp->code[MI_NUM_BREAKPOINTS] = 0; erts_smp_release_system(); if (c_p && c_p_locks) erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN); } modp->old_code = modp->code; modp->old_code_length = modp->code_length; modp->old_catches = modp->catches; modp->code = NULL; modp->code_length = 0; modp->catches = BEAM_CATCHES_NIL; }
Eterm erts_get_node_and_dist_references(struct process *proc) { Uint *hp; Uint size; Eterm res; #ifdef DEBUG Uint *endp; #endif erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); /* No need to lock any thing since we are alone... */ if (references_atoms_need_init) { INIT_AM(heap); INIT_AM(link); INIT_AM(monitor); INIT_AM(process); INIT_AM(port); INIT_AM(ets); INIT_AM(binary); INIT_AM(match_spec); INIT_AM(control); INIT_AM(dist); INIT_AM(node); INIT_AM(dist_references); INIT_AM(node_references); INIT_AM(timer); INIT_AM(system); #ifdef HYBRID INIT_AM(processes); #endif references_atoms_need_init = 0; } setup_reference_table(); /* Get term size */ size = 0; (void) reference_table_term(NULL, &size); hp = HAlloc(proc, size); #ifdef DEBUG ASSERT(size > 0); endp = hp + size; #endif /* Write term */ res = reference_table_term(&hp, NULL); ASSERT(endp == hp); delete_reference_table(); erts_smp_release_system(); erts_smp_proc_lock(proc, ERTS_PROC_LOCK_MAIN); return res; }
BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3) { Eterm res; erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); erts_export_consolidate(); res = erts_make_stub_module(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); erts_smp_release_system(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); return res; }
BIF_RETTYPE purge_module_1(BIF_ALIST_1) { int purge_res; if (is_not_atom(BIF_ARG_1)) { BIF_ERROR(BIF_P, BADARG); } erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); erts_export_consolidate(); purge_res = purge_module(atom_val(BIF_ARG_1)); erts_smp_release_system(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); if (purge_res < 0) { BIF_ERROR(BIF_P, BADARG); } BIF_RET(am_true); }
BIF_RETTYPE delete_module_1(BIF_ALIST_1) { int res; if (is_not_atom(BIF_ARG_1)) goto badarg; erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); { Module *modp = erts_get_module(BIF_ARG_1); if (!modp) { res = am_undefined; } else if (modp->old_code != 0) { erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); erts_dsprintf(dsbufp, "Module %T must be purged before loading\n", BIF_ARG_1); erts_send_error_to_logger(BIF_P->group_leader, dsbufp); res = am_badarg; } else { delete_export_references(BIF_ARG_1); delete_code(BIF_P, 0, modp); res = am_true; } } erts_smp_release_system(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); if (res == am_badarg) { badarg: BIF_ERROR(BIF_P, BADARG); } BIF_RET(res); }
Eterm load_module_2(BIF_ALIST_2) { Eterm reason; Eterm* hp; int i; int sz; byte* code; int trace_pattern_is_on; Binary *match_spec; Binary *meta_match_spec; struct trace_pattern_flags trace_pattern_flags; Eterm meta_tracer_pid; Eterm res; byte* temp_alloc = NULL; if (is_not_atom(BIF_ARG_1)) { error: erts_free_aligned_binary_bytes(temp_alloc); BIF_ERROR(BIF_P, BADARG); } if ((code = erts_get_aligned_binary_bytes(BIF_ARG_2, &temp_alloc)) == NULL) { goto error; } erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); erts_export_consolidate(); hp = HAlloc(BIF_P, 3); sz = binary_size(BIF_ARG_2); if ((i = erts_load_module(BIF_P, 0, BIF_P->group_leader, &BIF_ARG_1, code, sz)) < 0) { switch (i) { case -1: reason = am_badfile; break; case -2: reason = am_nofile; break; case -3: reason = am_not_purged; break; case -4: reason = am_atom_put("native_code", sizeof("native_code")-1); break; default: reason = am_badfile; break; } res = TUPLE2(hp, am_error, reason); goto done; } erts_get_default_trace_pattern(&trace_pattern_is_on, &match_spec, &meta_match_spec, &trace_pattern_flags, &meta_tracer_pid); if (trace_pattern_is_on) { Eterm mfa[1]; mfa[0] = BIF_ARG_1; (void) erts_set_trace_pattern(mfa, 1, match_spec, meta_match_spec, 1, trace_pattern_flags, meta_tracer_pid); } res = TUPLE2(hp, am_module, BIF_ARG_1); done: erts_free_aligned_binary_bytes(temp_alloc); erts_smp_release_system(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); BIF_RET(res); }
static void system_cleanup(int exit_code) { /* No cleanup wanted if ... * 1. we are about to do an abnormal exit * 2. we haven't finished initializing, or * 3. another thread than the main thread is performing the exit * (in threaded non smp case). */ if (exit_code != 0 || !erts_initialized #if defined(USE_THREADS) && !defined(ERTS_SMP) || !erts_equal_tids(main_thread, erts_thr_self()) #endif ) return; #ifdef ERTS_SMP #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_check_exact(NULL, 0); #endif erts_smp_block_system(ERTS_BS_FLG_ALLOW_GC); /* We never release it... */ #endif #ifdef HYBRID if (ma_src_stack) erts_free(ERTS_ALC_T_OBJECT_STACK, (void *)ma_src_stack); if (ma_dst_stack) erts_free(ERTS_ALC_T_OBJECT_STACK, (void *)ma_dst_stack); if (ma_offset_stack) erts_free(ERTS_ALC_T_OBJECT_STACK, (void *)ma_offset_stack); ma_src_stack = NULL; ma_dst_stack = NULL; ma_offset_stack = NULL; erts_cleanup_offheap(&erts_global_offheap); #endif #if defined(HYBRID) && !defined(INCREMENTAL) if (global_heap) { ERTS_HEAP_FREE(ERTS_ALC_T_HEAP, (void*) global_heap, sizeof(Eterm) * global_heap_sz); } global_heap = NULL; #endif #ifdef INCREMENTAL erts_cleanup_incgc(); #endif #if defined(USE_THREADS) exit_async(); #endif #if HAVE_ERTS_MSEG erts_mseg_exit(); #endif /* * A lot more cleaning could/should have been done... */ }
Eterm load_module_2(BIF_ALIST_2) { Eterm reason; Eterm* hp; int i; int sz; byte* code; Eterm res; byte* temp_alloc = NULL; if (is_not_atom(BIF_ARG_1)) { error: erts_free_aligned_binary_bytes(temp_alloc); BIF_ERROR(BIF_P, BADARG); } if ((code = erts_get_aligned_binary_bytes(BIF_ARG_2, &temp_alloc)) == NULL) { goto error; } erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); erts_export_consolidate(); hp = HAlloc(BIF_P, 3); sz = binary_size(BIF_ARG_2); if ((i = erts_load_module(BIF_P, 0, BIF_P->group_leader, &BIF_ARG_1, code, sz)) < 0) { switch (i) { case -1: reason = am_badfile; break; case -2: reason = am_nofile; break; case -3: reason = am_not_purged; break; case -4: reason = am_atom_put("native_code", sizeof("native_code")-1); break; case -5: { /* * The module contains an on_load function. The loader * has loaded the module as usual, except that the * export entries does not point into the module, so it * is not possible to call any code in the module. */ ERTS_DECL_AM(on_load); reason = AM_on_load; break; } default: reason = am_badfile; break; } res = TUPLE2(hp, am_error, reason); goto done; } set_default_trace_pattern(BIF_ARG_1); res = TUPLE2(hp, am_module, BIF_ARG_1); done: erts_free_aligned_binary_bytes(temp_alloc); erts_smp_release_system(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); BIF_RET(res); }
BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) { Module* modp = erts_get_module(BIF_ARG_1); Eterm on_load; if (!modp || modp->code == 0) { error: BIF_ERROR(BIF_P, BADARG); } if ((on_load = modp->code[MI_ON_LOAD_FUNCTION_PTR]) == 0) { goto error; } if (BIF_ARG_2 != am_false && BIF_ARG_2 != am_true) { goto error; } erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_block_system(0); if (BIF_ARG_2 == am_true) { int i; /* * The on_load function succeded. Fix up export entries. */ for (i = 0; i < export_list_size(); i++) { Export *ep = export_list(i); if (ep != NULL && ep->code[0] == BIF_ARG_1 && ep->code[4] != 0) { ep->address = (void *) ep->code[4]; ep->code[3] = 0; ep->code[4] = 0; } } modp->code[MI_ON_LOAD_FUNCTION_PTR] = 0; set_default_trace_pattern(BIF_ARG_1); } else if (BIF_ARG_2 == am_false) { Eterm* code; Eterm* end; /* * The on_load function failed. Remove the loaded code. * This is an combination of delete and purge. We purge * the current code; the old code is not touched. */ erts_total_code_size -= modp->code_length; code = modp->code; end = (Eterm *)((char *)code + modp->code_length); erts_cleanup_funs_on_purge(code, end); beam_catches_delmod(modp->catches, code, modp->code_length); erts_free(ERTS_ALC_T_CODE, (void *) code); modp->code = NULL; modp->code_length = 0; modp->catches = BEAM_CATCHES_NIL; remove_from_address_table(code); } erts_smp_release_system(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); BIF_RET(am_true); }