int __libc_start_main (int (*main) (int, char **, char **), int argc, char **argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void *stack_end) { char **envp = argv + argc + 1; int result = main (argc, argv, envp); mtcp_sys_exit(result); while(1); }
int __libc_start_main (int (*main) (int, char **, char **), int argc, char **argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void *stack_end) { int mtcp_sys_errno; char **envp = argv + argc + 1; int result = main(argc, argv, envp); mtcp_sys_exit(result); (void)mtcp_sys_errno; /* Stop compiler warning about unused variable */ while(1); }
NO_OPTIMIZE int main(int argc, char *argv[], char **environ) { char *ckptImage = NULL; MtcpHeader mtcpHdr; int mtcp_sys_errno; int simulate = 0; if (argc == 1) { MTCP_PRINTF("***ERROR: This program should not be used directly.\n"); mtcp_sys_exit(1); } #if 0 MTCP_PRINTF("Attach for debugging."); {int x=1; while(x);} #endif // TODO(karya0): Remove vDSO checks after 2.4.0-rc3 release, and after testing. // Without mtcp_check_vdso, CentOS 7 fails on dmtcp3, dmtcp5, others. #define ENABLE_VDSO_CHECK // TODO(karya0): Remove this block and the corresponding file after sufficient // testing: including testing for __i386__, __arm__ and __aarch64__ #ifdef ENABLE_VDSO_CHECK /* i386 uses random addresses for vdso. Make sure that its location * will not conflict with other memory regions. * (Other arch's may also need this in the future. So, we do it for all.) * Note that we may need to keep the old and the new vdso. We may * have checkpointed inside gettimeofday inside the old vdso, and the * kernel, on restart, knows only the new vdso. */ mtcp_check_vdso(environ); #endif rinfo.fd = -1; rinfo.use_gdb = 0; rinfo.text_offset = -1; shift; while (argc > 0) { // Flags for standalone debugging if (argc == 1) { // We would use MTCP_PRINTF, but it's also for output of util/readdmtcp.sh mtcp_printf("Considering '%s' as a ckpt image.\n", argv[0]); ckptImage = argv[0]; break; } else if (mtcp_strcmp(argv[0], "--use-gdb") == 0) { rinfo.use_gdb = 1; shift; } else if (mtcp_strcmp(argv[0], "--text-offset") == 0) { rinfo.text_offset = mtcp_strtol(argv[1]); shift; shift; // Flags for call by dmtcp_restart follow here: } else if (mtcp_strcmp(argv[0], "--fd") == 0) { rinfo.fd = mtcp_strtol(argv[1]); shift; shift; } else if (mtcp_strcmp(argv[0], "--stderr-fd") == 0) { rinfo.stderr_fd = mtcp_strtol(argv[1]); shift; shift; } else if (mtcp_strcmp(argv[0], "--simulate") == 0) { simulate = 1; shift; } else { MTCP_PRINTF("MTCP Internal Error\n"); return -1; } } if ((rinfo.fd != -1) ^ (ckptImage == NULL)) { MTCP_PRINTF("***MTCP Internal Error\n"); mtcp_abort(); } if (rinfo.fd != -1) { mtcp_readfile(rinfo.fd, &mtcpHdr, sizeof mtcpHdr); } else { int rc = -1; rinfo.fd = mtcp_sys_open2(ckptImage, O_RDONLY); if (rinfo.fd == -1) { MTCP_PRINTF("***ERROR opening ckpt image (%s); errno: %d\n", ckptImage, mtcp_sys_errno); mtcp_abort(); } // This assumes that the MTCP header signature is unique. // We repeatedly look for mtcpHdr because the first header will be // for DMTCP. So, we look deeper for the MTCP header. The MTCP // header is guaranteed to start on an offset that's an integer // multiple of sizeof(mtcpHdr), which is currently 4096 bytes. do { rc = mtcp_readfile(rinfo.fd, &mtcpHdr, sizeof mtcpHdr); } while (rc > 0 && mtcp_strcmp(mtcpHdr.signature, MTCP_SIGNATURE) != 0); if (rc == 0) { /* if end of file */ MTCP_PRINTF("***ERROR: ckpt image doesn't match MTCP_SIGNATURE\n"); return 1; /* exit with error code 1 */ } } DPRINTF("For debugging:\n" " (gdb) add-symbol-file ../../bin/mtcp_restart %p\n", mtcpHdr.restore_addr + rinfo.text_offset); if (rinfo.text_offset == -1) DPRINTF("... but add to the above the result, 1 +" " `text_offset.sh mtcp_restart`\n in the mtcp subdirectory.\n"); if (simulate) { mtcp_simulateread(rinfo.fd, &mtcpHdr); return 0; } rinfo.saved_brk = mtcpHdr.saved_brk; rinfo.restore_addr = mtcpHdr.restore_addr; rinfo.restore_end = mtcpHdr.restore_addr + mtcpHdr.restore_size; rinfo.restore_size = mtcpHdr.restore_size; rinfo.vdsoStart = mtcpHdr.vdsoStart; rinfo.vdsoEnd = mtcpHdr.vdsoEnd; rinfo.vvarStart = mtcpHdr.vvarStart; rinfo.vvarEnd = mtcpHdr.vvarEnd; rinfo.post_restart = mtcpHdr.post_restart; rinfo.motherofall_tls_info = mtcpHdr.motherofall_tls_info; rinfo.tls_pid_offset = mtcpHdr.tls_pid_offset; rinfo.tls_tid_offset = mtcpHdr.tls_tid_offset; rinfo.myinfo_gs = mtcpHdr.myinfo_gs; restore_brk(rinfo.saved_brk, rinfo.restore_addr, rinfo.restore_addr + rinfo.restore_size); getTextAddr(&rinfo.text_addr, &rinfo.text_size); if (hasOverlappingMapping(rinfo.restore_addr, rinfo.restore_size)) { MTCP_PRINTF("*** Not Implemented.\n\n"); mtcp_abort(); restart_slow_path(); } else { restart_fast_path(); } return 0; /* Will not reach here, but need to satisfy the compiler */ }