void default_actor_addressing::write(serializer* sink, const actor_ptr& ptr) { CPPA_REQUIRE(sink != nullptr); if (ptr == nullptr) { CPPA_LOGMF(CPPA_DEBUG, self, "serialized nullptr"); sink->begin_object("@0"); sink->end_object(); } else { // local actor? if (!ptr->is_proxy()) { get_actor_registry()->put(ptr->id(), ptr); } auto pinf = m_pinf; if (ptr->is_proxy()) { auto dptr = ptr.downcast<default_actor_proxy>(); if (dptr) pinf = dptr->process_info(); else CPPA_LOGMF(CPPA_ERROR, self, "downcast failed"); } sink->begin_object("@actor"); sink->write_value(ptr->id()); sink->write_value(pinf->process_id()); sink->write_raw(process_information::node_id_size, pinf->node_id().data()); sink->end_object(); } }
/* * We treat lstat the same as read except that only the existence or * nonexistence of the file is stored (represented as either the all * zero hash or the all one hash). */ int action_lstat(const char *path) { // Not all programs access files in a correct acyclic order. // In particular, GNU as stats its output .o file before writing // it. To fix this flaw, we lie to GNU as and pretend the file // is never there when statted. // TODO: This mechanism should be generalized and moved into a user // customizable file. struct process *process = process_info(); if ((process->flags & HACK_SKIP_O_STAT) && endswith(path, ".o")) { wlog("skipping stat(\"%s\")", path); return 0; } process = lock_master_process(); // Add a stat node to the subgraph struct hash path_hash; remember_hash_path(&path_hash, path); new_node(process, SG_STAT, &path_hash); // Check existence and update snapshot struct hash exists_hash; struct snapshot_entry *entry = snapshot_update(&exists_hash, path, &path_hash, 0); // No need to check for writers; if the file is being written, it must exist entry->stat = 1; shared_map_unlock(&snapshot); add_parent(process, &exists_hash); unlock_master_process(); return !hash_is_null(&exists_hash); }
int main() { int sock_fd,conn_fd; int client_len; pid_t pid; struct sockaddr_in addr_serv,addr_client; sock_fd = socket(AF_INET,SOCK_STREAM,0); if(sock_fd < 0){ perror("socket"); exit(1); } else { printf("sock sucessful\n"); } //初始化服务器端地址 memset(&addr_serv,0,sizeof(addr_serv)); addr_serv.sin_family = AF_INET; addr_serv.sin_port = htons(SOURCE_PORT); addr_serv.sin_addr.s_addr =inet_addr(SOURCE_IP_ADDRESS); client_len = sizeof(struct sockaddr_in); if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0){ perror("bind"); exit(1); } else { printf("bind sucess\n"); } if (listen(sock_fd,QUEUE_LINE) < 0){ perror("listen"); exit(1); } else { printf("listen sucessful\n"); } // while(1){ printf("begin accept:\n"); conn_fd = accept(sock_fd,(struct sockaddr *)&addr_client,&client_len); if(conn_fd < 0){ perror("accept"); exit(1); } printf("accept a new client,ip:%s\n",inet_ntoa(addr_client.sin_addr)); /* pid = fork(); if(0 == pid){ //子进程 close(sock_fd);//在子进程中关闭服务器的侦听 process_info(conn_fd);//处理信息 } else { close(conn_fd);//在父进程中关闭客户端的连接 }*/ close(sock_fd);//在子进程中关闭服务器的侦听 process_info(conn_fd);// // close(conn_fd); // } }
void LIR_OopMapGenerator::iterate_one(BlockBegin* block) { #ifndef PRODUCT if (TraceLIROopMaps) { tty->print_cr("Iterating through block %d", block->block_id()); } #endif set_block(block); block->set(BlockBegin::lir_oop_map_gen_reachable_flag); int i; if (!is_caching_change_block(block)) { LIR_OpVisitState state; LIR_OpList* inst = block->lir()->instructions_list(); int length = inst->length(); for (i = 0; i < length; i++) { LIR_Op* op = inst->at(i); LIR_Code code = op->code(); state.visit(op); for (int j = 0; j < state.info_count(); j++) { process_info(state.info_at(j)); } if (code == lir_volatile_move || code == lir_move) { process_move(op); } } } // Process successors if (block->end() != _base) { for (i = 0; i < block->end()->number_of_sux(); i++) { merge_state(block->end()->sux_at(i)); } } else { // Do not traverse OSR entry point of the base merge_state(_base->std_entry()); } set_block(NULL); }
static int process_list(int size, SFInfo *sf, FILE *fd) { SFChunk chunk; /* read the following id string */ READID(chunk.id, fd); size -= 4; switch (chunkid(chunk.id)) { case INFO_ID: return process_info(size, sf, fd); case SDTA_ID: return process_sdta(size, sf, fd); case PDTA_ID: return process_pdta(size, sf, fd); default: fprintf(stderr, "*** illegal id in level 1: %4.4s\n", chunk.id); FSKIP(size, fd); /* skip it */ return 0; } }
int Instruments::process_list(int size, SFInfo *sf, struct timidity_file *fd) { SFChunk chunk; /* read the following id string */ READID(chunk.id, fd); size -= 4; ctl_cmsg(CMSG_INFO, VERB_DEBUG, "%c%c%c%c:", chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]); switch (chunkid(chunk.id)) { case INFO_ID: return process_info(size, sf, fd); case SDTA_ID: return process_sdta(size, sf, fd); case PDTA_ID: return process_pdta(size, sf, fd); default: ctl_cmsg(CMSG_WARNING, VERB_NORMAL, "%s: *** illegal id in level 1: %4.4s", fd->filename.c_str(), chunk.id); FSKIP(size, fd); /* skip it */ return 0; } }
static inline void stat() { SYSTIME uptime; int i; unsigned int diff; get_uptime(&uptime); for (i = 0; i < TEST_ROUNDS; ++i) svc_test(); diff = systime_elapsed_us(&uptime); printf("average kernel call time: %d.%dus\n", diff / TEST_ROUNDS, (diff / (TEST_ROUNDS / 10)) % 10); get_uptime(&uptime); for (i = 0; i < TEST_ROUNDS; ++i) process_switch_test(); diff = systime_elapsed_us(&uptime); printf("average switch time: %d.%dus\n", diff / TEST_ROUNDS, (diff / (TEST_ROUNDS / 10)) % 10); printf("core clock: %d\n", power_get_core_clock()); process_info(); }
void default_actor_addressing::write(serializer* sink, const actor_ptr& ptr) { CPPA_REQUIRE(sink != nullptr); if (ptr == nullptr) { CPPA_LOG_DEBUG("serialize nullptr"); sink->write_value(static_cast<actor_id>(0)); process_information::serialize_invalid(sink); } else { // local actor? if (!ptr->is_proxy()) { get_actor_registry()->put(ptr->id(), ptr); } auto pinf = m_pinf; if (ptr->is_proxy()) { auto dptr = ptr.downcast<default_actor_proxy>(); if (dptr) pinf = dptr->process_info(); else CPPA_LOG_ERROR("downcast failed"); } sink->write_value(ptr->id()); sink->write_value(pinf->process_id()); sink->write_raw(process_information::node_id_size, pinf->node_id().data()); } }
/* XXX THIS SHOULD BE IN SYSTEM !!!! */ void erl_crash_dump_v(char *file, int line, char* fmt, va_list args) { #ifdef ERTS_SMP ErtsThrPrgrData tpd_buf; /* in case we aren't a managed thread... */ #endif int fd; size_t envsz; time_t now; char env[21]; /* enough to hold any 64-bit integer */ size_t dumpnamebufsize = MAXPATHLEN; char dumpnamebuf[MAXPATHLEN]; char* dumpname; int secs; int env_erl_crash_dump_seconds_set = 1; int i; if (ERTS_SOMEONE_IS_CRASH_DUMPING) return; #ifdef ERTS_SMP /* Order all managed threads to block, this has to be done first to guarantee that this is the only thread to generate crash dump. */ erts_thr_progress_fatal_error_block(&tpd_buf); #ifdef ERTS_THR_HAVE_SIG_FUNCS /* * We suspend all scheduler threads so that we can dump some * data about the currently running processes and scheduler data. * We have to be very very careful when doing this as the schedulers * could be anywhere. */ for (i = 0; i < erts_no_schedulers; i++) { erts_tid_t tid = ERTS_SCHEDULER_IX(i)->tid; if (!erts_equal_tids(tid,erts_thr_self())) sys_thr_suspend(tid); } #endif /* Allow us to pass certain places without locking... */ erts_smp_atomic32_set_mb(&erts_writing_erl_crash_dump, 1); erts_smp_tsd_set(erts_is_crash_dumping_key, (void *) 1); #else /* !ERTS_SMP */ erts_writing_erl_crash_dump = 1; #endif /* ERTS_SMP */ envsz = sizeof(env); /* ERL_CRASH_DUMP_SECONDS not set * if we have a heart port, break immediately * otherwise dump crash indefinitely (until crash is complete) * same as ERL_CRASH_DUMP_SECONDS = 0 * - do not write dump * - do not set an alarm * - break immediately * * ERL_CRASH_DUMP_SECONDS = 0 * - do not write dump * - do not set an alarm * - break immediately * * ERL_CRASH_DUMP_SECONDS < 0 * - do not set alarm * - write dump until done * * ERL_CRASH_DUMP_SECONDS = S (and S positive) * - Don't dump file forever * - set alarm (set in sys) * - write dump until alarm or file is written completely */ if (erts_sys_getenv__("ERL_CRASH_DUMP_SECONDS", env, &envsz) != 0) { env_erl_crash_dump_seconds_set = 0; secs = -1; } else { env_erl_crash_dump_seconds_set = 1; secs = atoi(env); } if (secs == 0) { return; } /* erts_sys_prepare_crash_dump returns 1 if heart port is found, otherwise 0 * If we don't find heart (0) and we don't have ERL_CRASH_DUMP_SECONDS set * we should continue writing a dump * * beware: secs -1 means no alarm */ if (erts_sys_prepare_crash_dump(secs) && !env_erl_crash_dump_seconds_set ) { return; } if (erts_sys_getenv__("ERL_CRASH_DUMP",&dumpnamebuf[0],&dumpnamebufsize) != 0) dumpname = "erl_crash.dump"; else dumpname = &dumpnamebuf[0]; erts_fprintf(stderr,"\nCrash dump is being written to: %s...", dumpname); fd = open(dumpname,O_WRONLY | O_CREAT | O_TRUNC,0640); if (fd < 0) return; /* Can't create the crash dump, skip it */ time(&now); erts_fdprintf(fd, "=erl_crash_dump:0.3\n%s", ctime(&now)); if (file != NULL) erts_fdprintf(fd, "The error occurred in file %s, line %d\n", file, line); if (fmt != NULL && *fmt != '\0') { erts_fdprintf(fd, "Slogan: "); erts_vfdprintf(fd, fmt, args); } erts_fdprintf(fd, "System version: "); erts_print_system_version(fd, NULL, NULL); erts_fdprintf(fd, "%s\n", "Compiled: " ERLANG_COMPILE_DATE); erts_fdprintf(fd, "Taints: "); erts_print_nif_taints(fd, NULL); erts_fdprintf(fd, "Atoms: %d\n", atom_table_size()); #ifdef USE_THREADS /* We want to note which thread it was that called erl_exit */ if (erts_get_scheduler_data()) { erts_fdprintf(fd, "Calling Thread: scheduler:%d\n", erts_get_scheduler_data()->no); } else { if (!erts_thr_getname(erts_thr_self(), dumpnamebuf, MAXPATHLEN)) erts_fdprintf(fd, "Calling Thread: %s\n", dumpnamebuf); else erts_fdprintf(fd, "Calling Thread: %p\n", erts_thr_self()); } #else erts_fdprintf(fd, "Calling Thread: scheduler:1\n"); #endif #if defined(ERTS_HAVE_TRY_CATCH) /* * erts_print_scheduler_info is not guaranteed to be safe to call * here for all schedulers as we may have suspended a scheduler * in the middle of updating the STACK_TOP and STACK_START * variables and thus when scanning the stack we could get * segmentation faults. We protect against this very unlikely * scenario by using the ERTS_SYS_TRY_CATCH. */ for (i = 0; i < erts_no_schedulers; i++) { ERTS_SYS_TRY_CATCH( erts_print_scheduler_info(fd, NULL, ERTS_SCHEDULER_IX(i)), erts_fdprintf(fd, "** crashed **\n")); } #endif #ifdef ERTS_SMP #if defined(ERTS_THR_HAVE_SIG_FUNCS) /* We resume all schedulers so that we are in a known safe state when we write the rest of the crash dump */ for (i = 0; i < erts_no_schedulers; i++) { erts_tid_t tid = ERTS_SCHEDULER_IX(i)->tid; if (!erts_equal_tids(tid,erts_thr_self())) sys_thr_resume(tid); } #endif /* * Wait for all managed threads to block. If all threads haven't blocked * after a minute, we go anyway and hope for the best... * * We do not release system again. We expect an exit() or abort() after * dump has been written. */ erts_thr_progress_fatal_error_wait(60000); /* Either worked or not... */ #endif #ifndef ERTS_HAVE_TRY_CATCH /* This is safe to call here, as all schedulers are blocked */ for (i = 0; i < erts_no_schedulers; i++) { erts_print_scheduler_info(fd, NULL, ERTS_SCHEDULER_IX(i)); } #endif info(fd, NULL); /* General system info */ if (erts_ptab_initialized(&erts_proc)) process_info(fd, NULL); /* Info about each process and port */ db_info(fd, NULL, 0); erts_print_bif_timer_info(fd, NULL); distribution_info(fd, NULL); erts_fdprintf(fd, "=loaded_modules\n"); loaded(fd, NULL); erts_dump_fun_entries(fd, NULL); erts_deep_process_dump(fd, NULL); erts_fdprintf(fd, "=atoms\n"); dump_atoms(fd, NULL); /* Keep the instrumentation data at the end of the dump */ if (erts_instr_memory_map || erts_instr_stat) { erts_fdprintf(fd, "=instr_data\n"); if (erts_instr_stat) { erts_fdprintf(fd, "=memory_status\n"); erts_instr_dump_stat_to_fd(fd, 0); } if (erts_instr_memory_map) { erts_fdprintf(fd, "=memory_map\n"); erts_instr_dump_memory_map_to_fd(fd); } } erts_fdprintf(fd, "=end\n"); close(fd); erts_fprintf(stderr,"done\n"); }
void do_break(void) { int i; #ifdef __WIN32__ char *mode; /* enough for storing "window" */ /* check if we're in console mode and, if so, halt immediately if break is called */ mode = erts_read_env("ERL_CONSOLE_MODE"); if (mode && strcmp(mode, "window") != 0) erl_exit(0, ""); erts_free_read_env(mode); #endif /* __WIN32__ */ erts_printf("\n" "BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded\n" " (v)ersion (k)ill (D)b-tables (d)istribution\n"); while (1) { if ((i = sys_get_key(0)) <= 0) erl_exit(0, ""); switch (i) { case 'q': case 'a': case '*': /* * The asterisk is an read error on windows, * where sys_get_key isn't that great in console mode. * The usual reason for a read error is Ctrl-C. Treat this as * 'a' to avoid infinite loop. */ erl_exit(0, ""); case 'A': /* Halt generating crash dump */ erl_exit(1, "Crash dump requested by user"); case 'c': return; case 'p': process_info(ERTS_PRINT_STDOUT, NULL); return; case 'm': return; case 'o': port_info(ERTS_PRINT_STDOUT, NULL); return; case 'i': info(ERTS_PRINT_STDOUT, NULL); return; case 'l': loaded(ERTS_PRINT_STDOUT, NULL); return; case 'v': erts_printf("Erlang (%s) emulator version " ERLANG_VERSION "\n", EMULATOR); erts_printf("Compiled on " ERLANG_COMPILE_DATE "\n"); return; case 'd': distribution_info(ERTS_PRINT_STDOUT, NULL); return; case 'D': db_info(ERTS_PRINT_STDOUT, NULL, 1); return; case 'k': process_killer(); return; #ifdef OPPROF case 'X': dump_frequencies(); return; case 'x': { int i; for (i = 0; i <= HIGHEST_OP; i++) { if (opc[i].name != NULL) { erts_printf("%-16s %8d\n", opc[i].name, opc[i].count); } } } return; case 'z': { int i; for (i = 0; i <= HIGHEST_OP; i++) opc[i].count = 0; } return; #endif #ifdef DEBUG case 't': erts_p_slpq(); return; case 'b': bin_check(); return; case 'C': abort(); #endif case '\n': continue; default: erts_printf("Eh?\n\n"); } } }
/* XXX THIS SHOULD BE IN SYSTEM !!!! */ void erl_crash_dump_v(char *file, int line, char* fmt, va_list args) { #ifdef ERTS_SMP ErtsThrPrgrData tpd_buf; /* in case we aren't a managed thread... */ #endif int fd; size_t envsz; time_t now; char env[21]; /* enough to hold any 64-bit integer */ size_t dumpnamebufsize = MAXPATHLEN; char dumpnamebuf[MAXPATHLEN]; char* dumpname; int secs; int env_erl_crash_dump_seconds_set = 1; if (ERTS_SOMEONE_IS_CRASH_DUMPING) return; #ifdef ERTS_SMP /* * Wait for all managed threads to block. If all threads haven't blocked * after a minute, we go anyway and hope for the best... * * We do not release system again. We expect an exit() or abort() after * dump has been written. */ erts_thr_progress_fatal_error_block(60000, &tpd_buf); /* Either worked or not... */ /* Allow us to pass certain places without locking... */ erts_smp_atomic32_set_mb(&erts_writing_erl_crash_dump, 1); erts_smp_tsd_set(erts_is_crash_dumping_key, (void *) 1); #else erts_writing_erl_crash_dump = 1; #endif envsz = sizeof(env); /* ERL_CRASH_DUMP_SECONDS not set * if we have a heart port, break immediately * otherwise dump crash indefinitely (until crash is complete) * same as ERL_CRASH_DUMP_SECONDS = 0 * - do not write dump * - do not set an alarm * - break immediately * * ERL_CRASH_DUMP_SECONDS = 0 * - do not write dump * - do not set an alarm * - break immediately * * ERL_CRASH_DUMP_SECONDS < 0 * - do not set alarm * - write dump until done * * ERL_CRASH_DUMP_SECONDS = S (and S positive) * - Don't dump file forever * - set alarm (set in sys) * - write dump until alarm or file is written completely */ if (erts_sys_getenv__("ERL_CRASH_DUMP_SECONDS", env, &envsz) != 0) { env_erl_crash_dump_seconds_set = 0; secs = -1; } else { env_erl_crash_dump_seconds_set = 1; secs = atoi(env); } if (secs == 0) { return; } /* erts_sys_prepare_crash_dump returns 1 if heart port is found, otherwise 0 * If we don't find heart (0) and we don't have ERL_CRASH_DUMP_SECONDS set * we should continue writing a dump * * beware: secs -1 means no alarm */ if (erts_sys_prepare_crash_dump(secs) && !env_erl_crash_dump_seconds_set ) { return; } if (erts_sys_getenv__("ERL_CRASH_DUMP",&dumpnamebuf[0],&dumpnamebufsize) != 0) dumpname = "erl_crash.dump"; else dumpname = &dumpnamebuf[0]; fd = open(dumpname,O_WRONLY | O_CREAT | O_TRUNC,0640); if (fd < 0) return; /* Can't create the crash dump, skip it */ time(&now); erts_fdprintf(fd, "=erl_crash_dump:0.3\n%s", ctime(&now)); if (file != NULL) erts_fdprintf(fd, "The error occurred in file %s, line %d\n", file, line); if (fmt != NULL && *fmt != '\0') { erts_fdprintf(fd, "Slogan: "); erts_vfdprintf(fd, fmt, args); } erts_fdprintf(fd, "System version: "); erts_print_system_version(fd, NULL, NULL); erts_fdprintf(fd, "%s\n", "Compiled: " ERLANG_COMPILE_DATE); erts_fdprintf(fd, "Taints: "); erts_print_nif_taints(fd, NULL); erts_fdprintf(fd, "Atoms: %d\n", atom_table_size()); info(fd, NULL); /* General system info */ if (erts_ptab_initialized(&erts_proc)) process_info(fd, NULL); /* Info about each process and port */ db_info(fd, NULL, 0); erts_print_bif_timer_info(fd, NULL); distribution_info(fd, NULL); erts_fdprintf(fd, "=loaded_modules\n"); loaded(fd, NULL); erts_dump_fun_entries(fd, NULL); erts_deep_process_dump(fd, NULL); erts_fdprintf(fd, "=atoms\n"); dump_atoms(fd, NULL); /* Keep the instrumentation data at the end of the dump */ if (erts_instr_memory_map || erts_instr_stat) { erts_fdprintf(fd, "=instr_data\n"); if (erts_instr_stat) { erts_fdprintf(fd, "=memory_status\n"); erts_instr_dump_stat_to_fd(fd, 0); } if (erts_instr_memory_map) { erts_fdprintf(fd, "=memory_map\n"); erts_instr_dump_memory_map_to_fd(fd); } } erts_fdprintf(fd, "=end\n"); close(fd); erts_fprintf(stderr,"\nCrash dump was written to: %s\n", dumpname); }
/* * action_execve adds an exec node to the subgraph and sets WAITLESS_PARENT * to the hash of the arguments. The first node in the child process will * use WAITLESS_PARENT as its first parent node. Note that WAITLESS_PARENT * is intentionally _not_ the same as the exec node; this encodes the idea * that child processes depend on their parent processes only through the * arguments to execve (and the current directory). * * In the case of shared spines (due to pipes or other IPC mechanisms) the * exec node encodes only the path without argv and envp and WAITLESS_PARENT * has the format #id where id is a SYSV shared memory id. This allows further * subgraph nodes from child and parent to be interleaved. Since in the shared * case the child _does_ descend directly from the exec node, an explicit * record of argv and envp would be redundant. */ int action_execve(const char *path, const char *const argv[], const char *const envp[]) { fd_map_dump(); struct process *process = lock_master_process(); int linked = process != process_info(); wlog("exec: linked %d", linked); // Pack all the arguments into a single buffer. The format is // char path[]; // uint32_t argc; // char argv[argc][]; // char is_pipe; // uint32_t envc; // char envp[envc][]; // char cwd[]; // with all strings packed together with terminating nulls. char data[4096]; char *p = data; #define ADD_STR(s) p += strlcpy(p, (s), data+sizeof(data)-p) + 1 ADD_STR(path); // encode argv char *cp = p; p += sizeof(uint32_t); // skip 4 bytes for len(argv) uint32_t i; for (i = 0; argv[i]; i++) ADD_STR(argv[i]); memcpy(cp, &i, sizeof(uint32_t)); *p++ = linked; // encode envp cp = p; p += sizeof(uint32_t); // skip 4 bytes for len(envp) uint32_t count; for (i = 0; envp[i]; i++) if (!startswith(envp[i], "WAITLESS")) { ADD_STR(envp[i]); count++; } memcpy(cp, &count, sizeof(uint32_t)); // encode pwd if (!real_getcwd(p, data+sizeof(data)-p)) die("action_execve: getcwd failed: %s", strerror(errno)); int n = p - data + strlen(p) + 1; #undef ADD_STR // Store exec data and create a corresponding exec node struct hash data_hash; remember_hash_memory(&data_hash, data, n); new_node(process, SG_EXEC, &data_hash); // Add the program to the snapshot struct hash path_hash, program_hash; remember_hash_path(&path_hash, path); struct snapshot_entry *entry = snapshot_update(&program_hash, path, &path_hash, 1); if (entry->writing) die("can't exec '%s' while it is being written", path); // TODO: block instead of dying entry->read = 1; shared_map_unlock(&snapshot); // TODO: Run ldd/otool and hash all shared library dependencies as well // TODO: Complain if the program is statically linked // TODO: If we decide it's worth it, parse #! lines and hash interpreters // too. That seems easy enough to probably be worth it. // If not linked, set parents to the new child values if (!linked) { process->parents.n = 2; process->parents.p[0] = data_hash; process->parents.p[1] = program_hash; } unlock_master_process(); // Update process flags process = lock_process(); int old_flags = process->flags; process->flags = 0; p = rindex(path, '/'); const char *name = p ? p+1 : path; if (!strcmp(name, "as")) process->flags |= HACK_SKIP_O_STAT; else if (strstr(name, "-gcc-")) { for (i = 1; argv[i]; i++) if (!strcmp(argv[i], "-c")) { process->flags |= HACK_SKIP_O_STAT; break; } } unlock_process(); // Do the exec int ret = real_execve(path, argv, envp); // An error must have occurred; reset flags back to old value process = lock_process(); process->flags = old_flags; unlock_process(); return ret; }
/* XXX THIS SHOULD BE IN SYSTEM !!!! */ void erl_crash_dump_v(char *file, int line, char* fmt, va_list args) { #ifdef ERTS_SMP ErtsThrPrgrData tpd_buf; /* in case we aren't a managed thread... */ #endif int fd; time_t now; size_t dumpnamebufsize = MAXPATHLEN; char dumpnamebuf[MAXPATHLEN]; char* dumpname; if (ERTS_SOMEONE_IS_CRASH_DUMPING) return; #ifdef ERTS_SMP /* * Wait for all managed threads to block. If all threads haven't blocked * after a minute, we go anyway and hope for the best... * * We do not release system again. We expect an exit() or abort() after * dump has been written. */ erts_thr_progress_fatal_error_block(60000, &tpd_buf); /* Either worked or not... */ /* Allow us to pass certain places without locking... */ erts_smp_atomic32_set_mb(&erts_writing_erl_crash_dump, 1); erts_smp_tsd_set(erts_is_crash_dumping_key, (void *) 1); #else erts_writing_erl_crash_dump = 1; #endif erts_sys_prepare_crash_dump(); if (erts_sys_getenv_raw("ERL_CRASH_DUMP",&dumpnamebuf[0],&dumpnamebufsize) != 0) dumpname = "erl_crash.dump"; else dumpname = &dumpnamebuf[0]; fd = open(dumpname,O_WRONLY | O_CREAT | O_TRUNC,0640); if (fd < 0) return; /* Can't create the crash dump, skip it */ time(&now); erts_fdprintf(fd, "=erl_crash_dump:0.1\n%s", ctime(&now)); if (file != NULL) erts_fdprintf(fd, "The error occurred in file %s, line %d\n", file, line); if (fmt != NULL && *fmt != '\0') { erts_fdprintf(fd, "Slogan: "); erts_vfdprintf(fd, fmt, args); } erts_fdprintf(fd, "System version: "); erts_print_system_version(fd, NULL, NULL); erts_fdprintf(fd, "%s\n", "Compiled: " ERLANG_COMPILE_DATE); erts_fdprintf(fd, "Taints: "); erts_print_nif_taints(fd, NULL); erts_fdprintf(fd, "Atoms: %d\n", atom_table_size()); info(fd, NULL); /* General system info */ if (erts_proc.tab) process_info(fd, NULL); /* Info about each process and port */ db_info(fd, NULL, 0); erts_print_bif_timer_info(fd, NULL); distribution_info(fd, NULL); erts_fdprintf(fd, "=loaded_modules\n"); loaded(fd, NULL); erts_dump_fun_entries(fd, NULL); erts_deep_process_dump(fd, NULL); erts_fdprintf(fd, "=atoms\n"); dump_atoms(fd, NULL); /* Keep the instrumentation data at the end of the dump */ if (erts_instr_memory_map || erts_instr_stat) { erts_fdprintf(fd, "=instr_data\n"); if (erts_instr_stat) { erts_fdprintf(fd, "=memory_status\n"); erts_instr_dump_stat_to_fd(fd, 0); } if (erts_instr_memory_map) { erts_fdprintf(fd, "=memory_map\n"); erts_instr_dump_memory_map_to_fd(fd); } } erts_fdprintf(fd, "=end\n"); close(fd); erts_fprintf(stderr,"\nCrash dump was written to: %s\n", dumpname); }