/* * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal * Method: attach0 * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0 (JNIEnv *env, jobject this_obj, jstring cmdLine) { jboolean isCopy; int gcode; const char* cmdLine_cstr = env->GetStringUTFChars(cmdLine, &isCopy); CHECK_EXCEPTION; struct ps_prochandle* Pr = proc_arg_grab(cmdLine_cstr, PR_ARG_ANY, PGRAB_FORCE, &gcode); env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr); if(! Pr) THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process/core file!"); env->SetLongField(this_obj, ps_prochandle_ptr_ID, (jlong) Pr); // initialize libthread_db pointers /* * Iterate over the process mappings looking * for libthread and then dlopen the appropriate * libthread_db and get pointers to functions. */ Debugger dbg; dbg.env = env; dbg.obj = this_obj; (void) Pobject_iter(Pr, object_iter, &dbg); CHECK_EXCEPTION; // get the user level threads info td_thragent_t *Tap = 0; p_td_init_t p_td_init = (p_td_init_t) env->GetLongField(this_obj, p_td_init_ID); if (p_td_init == 0) return; p_td_ta_new_t p_td_ta_new = (p_td_ta_new_t) env->GetLongField(this_obj, p_td_ta_new_ID); if (p_td_init() != TD_OK) THROW_NEW_DEBUGGER_EXCEPTION("Can't initialize thread_db!"); if (p_td_ta_new(Pr, &Tap) != TD_OK) THROW_NEW_DEBUGGER_EXCEPTION("Can't create thread_db agent!"); /* * Iterate over all threads, calling: * thr_stack(td_thrhandle_t *Thp, NULL); * for each one to generate the list of threads. */ p_td_ta_thr_iter_t p_td_ta_thr_iter = (p_td_ta_thr_iter_t) env->GetLongField(this_obj, p_td_ta_thr_iter_ID); (void) p_td_ta_thr_iter(Tap, thr_stack, &dbg, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); CHECK_EXCEPTION; p_td_ta_delete_t p_td_ta_delete = (p_td_ta_delete_t) env->GetLongField(this_obj, p_td_ta_delete_ID); (void) p_td_ta_delete(Tap); // Part of workaround for 4705086. /* * iterate over maps of the process/core to get first * libjvm[_g].so mapping. */ Pmapping_iter(Pr, iterate_map, &dbg); CHECK_EXCEPTION; /* * Get libjvm[_g].so text size. First location after the end of text segment * is marked by the global reserved symbol '_etext' in any ELF file. * Please refer to page 53 of "Linkers and Libraries Guide - 816-0559". */ psaddr_t etext_addr; if (ps_pglobal_lookup(Pr, "libjvm.so", "_etext", &etext_addr) != PS_OK) { // try the debug version if (ps_pglobal_lookup(Pr, "libjvm_g.so", "_etext", &etext_addr) != PS_OK) THROW_NEW_DEBUGGER_EXCEPTION("Can't get end of text address of libjvm!"); } // now calculate and set libjvm text size. jlong libjvm_text_start = env->GetLongField(this_obj, libjvm_text_start_ID); env->SetLongField(this_obj, libjvm_text_size_ID, (jlong) (etext_addr - libjvm_text_start)); }
int main(int argc, char **argv) { int rflag = 0, sflag = 0, xflag = 0, Fflag = 0; int errflg = 0, Sflag = 0; int rc = 0; int opt; const char *bar8 = "-------"; const char *bar16 = "----------"; const char *bar; struct rlimit rlim; struct stat64 statbuf; char buf[128]; int mapfd; int prg_gflags = PGRAB_RDONLY; int prr_flags = 0; boolean_t use_agent_lwp = B_FALSE; if ((command = strrchr(argv[0], '/')) != NULL) command++; else command = argv[0]; while ((opt = getopt(argc, argv, "arsxSlLFA:")) != EOF) { switch (opt) { case 'a': /* include shared mappings in -[xS] */ aflag = 1; break; case 'r': /* show reserved mappings */ rflag = 1; break; case 's': /* show hardware page sizes */ sflag = 1; break; case 'S': /* show swap reservations */ Sflag = 1; break; case 'x': /* show extended mappings */ xflag = 1; break; case 'l': /* show unresolved link map names */ lflag = 1; break; case 'L': /* show lgroup information */ Lflag = 1; use_agent_lwp = B_TRUE; break; case 'F': /* force grabbing (no O_EXCL) */ Fflag = PGRAB_FORCE; break; case 'A': if (parse_addr_range(optarg, &start_addr, &end_addr) != 0) errflg++; break; default: errflg = 1; break; } } argc -= optind; argv += optind; if ((Sflag && (xflag || rflag || sflag)) || (xflag && rflag) || (aflag && (!xflag && !Sflag)) || (Lflag && (xflag || Sflag))) { errflg = 1; } if (errflg || argc <= 0) { (void) fprintf(stderr, "usage:\t%s [-rslF] [-A start[,end]] { pid | core } ...\n", command); (void) fprintf(stderr, "\t\t(report process address maps)\n"); (void) fprintf(stderr, "\t%s -L [-rslF] [-A start[,end]] pid ...\n", command); (void) fprintf(stderr, "\t\t(report process address maps lgroups mappings)\n"); (void) fprintf(stderr, "\t%s -x [-aslF] [-A start[,end]] pid ...\n", command); (void) fprintf(stderr, "\t\t(show resident/anon/locked mapping details)\n"); (void) fprintf(stderr, "\t%s -S [-alF] [-A start[,end]] { pid | core } ...\n", command); (void) fprintf(stderr, "\t\t(show swap reservations)\n\n"); (void) fprintf(stderr, "\t-a: include shared mappings in -[xS] summary\n"); (void) fprintf(stderr, "\t-r: show reserved address maps\n"); (void) fprintf(stderr, "\t-s: show hardware page sizes\n"); (void) fprintf(stderr, "\t-l: show unresolved dynamic linker map names\n"); (void) fprintf(stderr, "\t-F: force grabbing of the target process\n"); (void) fprintf(stderr, "\t-L: show lgroup mappings\n"); (void) fprintf(stderr, "\t-A start,end: limit output to the specified range\n"); return (2); } /* * Make sure we'll have enough file descriptors to handle a target * that has many many mappings. */ if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { rlim.rlim_cur = rlim.rlim_max; (void) setrlimit(RLIMIT_NOFILE, &rlim); (void) enable_extended_FILE_stdio(-1, -1); } /* * The implementation of -L option creates an agent LWP in the target * process address space. The agent LWP issues meminfo(2) system calls * on behalf of the target process. If we are interrupted prematurely, * the target process remains in the stopped state with the agent still * attached to it. To prevent such situation we catch signals from * terminal and terminate gracefully. */ if (use_agent_lwp) { /* * Buffer output to stdout, stderr while process is grabbed. * Prevents infamous deadlocks due to pmap `pgrep xterm` and * other variants. */ (void) proc_initstdio(); prg_gflags = PGRAB_RETAIN | Fflag; prr_flags = PRELEASE_RETAIN; if (sigset(SIGHUP, SIG_IGN) == SIG_DFL) (void) sigset(SIGHUP, intr); if (sigset(SIGINT, SIG_IGN) == SIG_DFL) (void) sigset(SIGINT, intr); if (sigset(SIGQUIT, SIG_IGN) == SIG_DFL) (void) sigset(SIGQUIT, intr); (void) sigset(SIGPIPE, intr); (void) sigset(SIGTERM, intr); } while (argc-- > 0) { char *arg; int gcode; psinfo_t psinfo; int tries = 0; if (use_agent_lwp) (void) proc_flushstdio(); if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY, prg_gflags, &gcode)) == NULL) { (void) fprintf(stderr, "%s: cannot examine %s: %s\n", command, arg, Pgrab_error(gcode)); rc++; continue; } procname = arg; /* for perr() */ addr_width = (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) ? 16 : 8; size_width = (Pstatus(Pr)->pr_dmodel == PR_MODEL_LP64) ? 11 : 8; bar = addr_width == 8 ? bar8 : bar16; (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t)); proc_unctrl_psinfo(&psinfo); if (Pstate(Pr) != PS_DEAD) { (void) snprintf(buf, sizeof (buf), "/proc/%d/map", (int)psinfo.pr_pid); if ((mapfd = open(buf, O_RDONLY)) < 0) { (void) fprintf(stderr, "%s: cannot " "examine %s: lost control of " "process\n", command, arg); rc++; Prelease(Pr, prr_flags); continue; } } else { mapfd = -1; } again: map_count = 0; if (Pstate(Pr) == PS_DEAD) { (void) printf("core '%s' of %d:\t%.70s\n", arg, (int)psinfo.pr_pid, psinfo.pr_psargs); if (rflag || sflag || xflag || Sflag || Lflag) { (void) printf(" -%c option is not compatible " "with core files\n", xflag ? 'x' : sflag ? 's' : rflag ? 'r' : Lflag ? 'L' : 'S'); Prelease(Pr, prr_flags); rc++; continue; } } else { (void) printf("%d:\t%.70s\n", (int)psinfo.pr_pid, psinfo.pr_psargs); } if (!(Pstatus(Pr)->pr_flags & PR_ISSYS)) { struct totals t; /* * Since we're grabbing the process readonly, we need * to make sure the address space doesn't change during * execution. */ if (Pstate(Pr) != PS_DEAD) { if (tries++ == MAX_TRIES) { Prelease(Pr, prr_flags); (void) close(mapfd); (void) fprintf(stderr, "%s: cannot " "examine %s: address space is " "changing\n", command, arg); continue; } if (fstat64(mapfd, &statbuf) != 0) { Prelease(Pr, prr_flags); (void) close(mapfd); (void) fprintf(stderr, "%s: cannot " "examine %s: lost control of " "process\n", command, arg); continue; } } nstacks = psinfo.pr_nlwp * 2; stacks = calloc(nstacks, sizeof (stacks[0])); if (stacks != NULL) { int n = 0; (void) Plwp_iter(Pr, getstack, &n); qsort(stacks, nstacks, sizeof (stacks[0]), cmpstacks); } (void) memset(&t, 0, sizeof (t)); if (Pgetauxval(Pr, AT_BASE) != -1L && Prd_agent(Pr) == NULL) { (void) fprintf(stderr, "%s: warning: " "librtld_db failed to initialize; " "shared library information will not be " "available\n", command); } /* * Gather data */ if (xflag) rc += xmapping_iter(Pr, gather_xmap, NULL, 0); else if (Sflag) rc += xmapping_iter(Pr, gather_xmap, NULL, 1); else { if (rflag) rc += rmapping_iter(Pr, gather_map, NULL); else if (sflag) rc += xmapping_iter(Pr, gather_xmap, NULL, 0); else if (lflag) rc += Pmapping_iter(Pr, gather_map, NULL); else rc += Pmapping_iter_resolved(Pr, gather_map, NULL); } /* * Ensure mappings are consistent. */ if (Pstate(Pr) != PS_DEAD) { struct stat64 newbuf; if (fstat64(mapfd, &newbuf) != 0 || memcmp(&newbuf.st_mtim, &statbuf.st_mtim, sizeof (newbuf.st_mtim)) != 0) { if (stacks != NULL) { free(stacks); stacks = NULL; } goto again; } } /* * Display data. */ if (xflag) { (void) printf("%*s%*s%*s%*s%*s " "%sMode Mapped File\n", addr_width, "Address", size_width, "Kbytes", size_width, "RSS", size_width, "Anon", size_width, "Locked", sflag ? "Pgsz " : ""); rc += iter_xmap(sflag ? look_xmap : look_xmap_nopgsz, &t); (void) printf("%s%s %s %s %s %s\n", addr_width == 8 ? "-" : "------", bar, bar, bar, bar, bar); (void) printf("%stotal Kb", addr_width == 16 ? " " : ""); printK(t.total_size, size_width); printK(t.total_rss, size_width); printK(t.total_anon, size_width); printK(t.total_locked, size_width); (void) printf("\n"); } else if (Sflag) { (void) printf("%*s%*s%*s Mode" " Mapped File\n", addr_width, "Address", size_width, "Kbytes", size_width, "Swap"); rc += iter_xmap(look_xmap_nopgsz, &t); (void) printf("%s%s %s %s\n", addr_width == 8 ? "-" : "------", bar, bar, bar); (void) printf("%stotal Kb", addr_width == 16 ? " " : ""); printK(t.total_size, size_width); printK(t.total_swap, size_width); (void) printf("\n"); } else { if (rflag) { rc += iter_map(look_map, &t); } else if (sflag) { if (Lflag) { (void) printf("%*s %*s %4s" " %-6s %s %s\n", addr_width, "Address", size_width, "Bytes", "Pgsz", "Mode ", "Lgrp", "Mapped File"); rc += iter_xmap(look_smap, &t); } else { (void) printf("%*s %*s %4s" " %-6s %s\n", addr_width, "Address", size_width, "Bytes", "Pgsz", "Mode ", "Mapped File"); rc += iter_xmap(look_smap, &t); } } else { rc += iter_map(look_map, &t); } (void) printf(" %stotal %*luK\n", addr_width == 16 ? " " : "", size_width, t.total_size); } if (stacks != NULL) { free(stacks); stacks = NULL; } } Prelease(Pr, prr_flags); if (mapfd != -1) (void) close(mapfd); } if (use_agent_lwp) (void) proc_finistdio(); return (rc); }
/* * Don't explicity stop the process; that's up to the consumer. */ int Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) { char plat[SYS_NMLN]; char zonename[ZONENAME_MAX]; int platlen = -1; pgcore_t pgc; off64_t poff, soff, doff, boff; struct utsname uts; uint_t nphdrs, nshdrs; if (ftruncate64(fd, 0) != 0) return (-1); if (content == CC_CONTENT_INVALID) { errno = EINVAL; return (-1); } /* * Cache the mappings and other useful data. */ (void) Prd_agent(P); (void) Ppsinfo(P); pgc.P = P; pgc.pgc_fd = fd; pgc.pgc_poff = &poff; pgc.pgc_soff = &soff; pgc.pgc_doff = &doff; pgc.pgc_content = content; pgc.pgc_chunksz = PAGESIZE; if ((pgc.pgc_chunk = malloc(pgc.pgc_chunksz)) == NULL) return (-1); shstrtab_init(&pgc.pgc_shstrtab); /* * There are two PT_NOTE program headers for ancillary data, and * one for each mapping. */ nphdrs = 2 + P->map_count; nshdrs = count_sections(&pgc); (void) Pplatform(P, plat, sizeof (plat)); platlen = strlen(plat) + 1; Preadauxvec(P); (void) Puname(P, &uts); if (Pzonename(P, zonename, sizeof (zonename)) == NULL) zonename[0] = '\0'; /* * The core file contents may required zero section headers, but if we * overflow the 16 bits allotted to the program header count in the ELF * header, we'll need that program header at index zero. */ if (nshdrs == 0 && nphdrs >= PN_XNUM) nshdrs = 1; /* * Set up the ELF header. */ if (P->status.pr_dmodel == PR_MODEL_ILP32) { Elf32_Ehdr ehdr; bzero(&ehdr, sizeof (ehdr)); ehdr.e_ident[EI_MAG0] = ELFMAG0; ehdr.e_ident[EI_MAG1] = ELFMAG1; ehdr.e_ident[EI_MAG2] = ELFMAG2; ehdr.e_ident[EI_MAG3] = ELFMAG3; ehdr.e_type = ET_CORE; ehdr.e_ident[EI_CLASS] = ELFCLASS32; #if defined(__sparc) ehdr.e_machine = EM_SPARC; ehdr.e_ident[EI_DATA] = ELFDATA2MSB; #elif defined(__i386) || defined(__amd64) ehdr.e_machine = EM_386; ehdr.e_ident[EI_DATA] = ELFDATA2LSB; #else #error "unknown machine type" #endif ehdr.e_ident[EI_VERSION] = EV_CURRENT; ehdr.e_version = EV_CURRENT; ehdr.e_ehsize = sizeof (ehdr); if (nphdrs >= PN_XNUM) ehdr.e_phnum = PN_XNUM; else ehdr.e_phnum = (unsigned short)nphdrs; ehdr.e_phentsize = sizeof (Elf32_Phdr); ehdr.e_phoff = ehdr.e_ehsize; if (nshdrs > 0) { if (nshdrs >= SHN_LORESERVE) ehdr.e_shnum = 0; else ehdr.e_shnum = (unsigned short)nshdrs; if (nshdrs - 1 >= SHN_LORESERVE) ehdr.e_shstrndx = SHN_XINDEX; else ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); ehdr.e_shentsize = sizeof (Elf32_Shdr); ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; } if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) goto err; poff = ehdr.e_phoff; soff = ehdr.e_shoff; doff = boff = ehdr.e_ehsize + ehdr.e_phentsize * nphdrs + ehdr.e_shentsize * nshdrs; #ifdef _LP64 } else { Elf64_Ehdr ehdr; bzero(&ehdr, sizeof (ehdr)); ehdr.e_ident[EI_MAG0] = ELFMAG0; ehdr.e_ident[EI_MAG1] = ELFMAG1; ehdr.e_ident[EI_MAG2] = ELFMAG2; ehdr.e_ident[EI_MAG3] = ELFMAG3; ehdr.e_type = ET_CORE; ehdr.e_ident[EI_CLASS] = ELFCLASS64; #if defined(__sparc) ehdr.e_machine = EM_SPARCV9; ehdr.e_ident[EI_DATA] = ELFDATA2MSB; #elif defined(__i386) || defined(__amd64) ehdr.e_machine = EM_AMD64; ehdr.e_ident[EI_DATA] = ELFDATA2LSB; #else #error "unknown machine type" #endif ehdr.e_ident[EI_VERSION] = EV_CURRENT; ehdr.e_version = EV_CURRENT; ehdr.e_ehsize = sizeof (ehdr); if (nphdrs >= PN_XNUM) ehdr.e_phnum = PN_XNUM; else ehdr.e_phnum = (unsigned short)nphdrs; ehdr.e_phentsize = sizeof (Elf64_Phdr); ehdr.e_phoff = ehdr.e_ehsize; if (nshdrs > 0) { if (nshdrs >= SHN_LORESERVE) ehdr.e_shnum = 0; else ehdr.e_shnum = (unsigned short)nshdrs; if (nshdrs - 1 >= SHN_LORESERVE) ehdr.e_shstrndx = SHN_XINDEX; else ehdr.e_shstrndx = (unsigned short)(nshdrs - 1); ehdr.e_shentsize = sizeof (Elf64_Shdr); ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phentsize * nphdrs; } if (gc_pwrite64(fd, &ehdr, sizeof (ehdr), 0) != 0) goto err; poff = ehdr.e_phoff; soff = ehdr.e_shoff; doff = boff = ehdr.e_ehsize + ehdr.e_phentsize * nphdrs + ehdr.e_shentsize * nshdrs; #endif /* _LP64 */ } /* * Write the zero indexed section if it exists. */ if (nshdrs > 0 && write_shdr(&pgc, STR_NONE, 0, 0, 0, 0, nshdrs >= SHN_LORESERVE ? nshdrs : 0, nshdrs - 1 >= SHN_LORESERVE ? nshdrs - 1 : 0, nphdrs >= PN_XNUM ? nphdrs : 0, 0, 0) != 0) goto err; /* * Construct the old-style note header and section. */ if (P->status.pr_dmodel == PR_MODEL_NATIVE) { prpsinfo_t prpsinfo; mkprpsinfo(P, &prpsinfo); if (write_note(fd, NT_PRPSINFO, &prpsinfo, sizeof (prpsinfo_t), &doff) != 0) { goto err; } if (write_note(fd, NT_AUXV, P->auxv, P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { goto err; } #ifdef _LP64 } else { prpsinfo32_t pi32; auxv32_t *av32; size_t size = sizeof (auxv32_t) * P->nauxv; int i; mkprpsinfo32(P, &pi32); if (write_note(fd, NT_PRPSINFO, &pi32, sizeof (prpsinfo32_t), &doff) != 0) { goto err; } if ((av32 = malloc(size)) == NULL) goto err; for (i = 0; i < P->nauxv; i++) { auxv_n_to_32(&P->auxv[i], &av32[i]); } if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { free(av32); goto err; } free(av32); #endif /* _LP64 */ } if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0) goto err; if (Plwp_iter_all(P, old_per_lwp, &pgc) != 0) goto err; if (P->status.pr_dmodel == PR_MODEL_ILP32) { Elf32_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = (Elf32_Off)boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #ifdef _LP64 } else { Elf64_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #endif /* _LP64 */ } /* * Construct the new-style note header and section. */ if (P->status.pr_dmodel == PR_MODEL_NATIVE) { if (write_note(fd, NT_PSINFO, &P->psinfo, sizeof (psinfo_t), &doff) != 0) { goto err; } if (write_note(fd, NT_PSTATUS, &P->status, sizeof (pstatus_t), &doff) != 0) { goto err; } if (write_note(fd, NT_AUXV, P->auxv, P->nauxv * sizeof (P->auxv[0]), &doff) != 0) { goto err; } #ifdef _LP64 } else { psinfo32_t pi32; pstatus32_t ps32; auxv32_t *av32; size_t size = sizeof (auxv32_t) * P->nauxv; int i; psinfo_n_to_32(&P->psinfo, &pi32); if (write_note(fd, NT_PSINFO, &pi32, sizeof (psinfo32_t), &doff) != 0) { goto err; } pstatus_n_to_32(&P->status, &ps32); if (write_note(fd, NT_PSTATUS, &ps32, sizeof (pstatus32_t), &doff) != 0) { goto err; } if ((av32 = malloc(size)) == NULL) goto err; for (i = 0; i < P->nauxv; i++) { auxv_n_to_32(&P->auxv[i], &av32[i]); } if (write_note(fd, NT_AUXV, av32, size, &doff) != 0) { free(av32); goto err; } free(av32); #endif /* _LP64 */ } if (write_note(fd, NT_PLATFORM, plat, platlen, &doff) != 0 || write_note(fd, NT_UTSNAME, &uts, sizeof (uts), &doff) != 0 || write_note(fd, NT_CONTENT, &content, sizeof (content), &doff) != 0) goto err; { prcred_t cred, *cp; size_t size = sizeof (prcred_t); if (Pcred(P, &cred, 0) != 0) goto err; if (cred.pr_ngroups > 0) size += sizeof (gid_t) * (cred.pr_ngroups - 1); if ((cp = malloc(size)) == NULL) goto err; if (Pcred(P, cp, cred.pr_ngroups) != 0 || write_note(fd, NT_PRCRED, cp, size, &doff) != 0) { free(cp); goto err; } free(cp); } { prpriv_t *ppriv = NULL; const priv_impl_info_t *pinfo; size_t pprivsz, pinfosz; if (Ppriv(P, &ppriv) == -1) goto err; pprivsz = PRIV_PRPRIV_SIZE(ppriv); if (write_note(fd, NT_PRPRIV, ppriv, pprivsz, &doff) != 0) { Ppriv_free(P, ppriv); goto err; } Ppriv_free(P, ppriv); if ((pinfo = getprivimplinfo()) == NULL) goto err; pinfosz = PRIV_IMPL_INFO_SIZE(pinfo); if (write_note(fd, NT_PRPRIVINFO, pinfo, pinfosz, &doff) != 0) goto err; } if (write_note(fd, NT_ZONENAME, zonename, strlen(zonename) + 1, &doff) != 0) goto err; { fditer_t iter; iter.fd_fd = fd; iter.fd_doff = &doff; if (Pfdinfo_iter(P, iter_fd, &iter) != 0) goto err; } { prsecflags_t *psf = NULL; if (Psecflags(P, &psf) != 0) goto err; if (write_note(fd, NT_SECFLAGS, psf, sizeof (prsecflags_t), &doff) != 0) { Psecflags_free(psf); goto err; } Psecflags_free(psf); } #if defined(__i386) || defined(__amd64) /* CSTYLED */ { struct ssd *ldtp; size_t size; int nldt; /* * Only dump out non-zero sized LDT notes. */ if ((nldt = Pldt(P, NULL, 0)) != 0) { size = sizeof (struct ssd) * nldt; if ((ldtp = malloc(size)) == NULL) goto err; if (Pldt(P, ldtp, nldt) == -1 || write_note(fd, NT_LDT, ldtp, size, &doff) != 0) { free(ldtp); goto err; } free(ldtp); } } #endif /* __i386 || __amd64 */ if (Plwp_iter_all(P, new_per_lwp, &pgc) != 0) goto err; if (P->status.pr_dmodel == PR_MODEL_ILP32) { Elf32_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = (Elf32_Off)boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #ifdef _LP64 } else { Elf64_Phdr phdr; bzero(&phdr, sizeof (phdr)); phdr.p_type = PT_NOTE; phdr.p_flags = PF_R; phdr.p_offset = boff; phdr.p_filesz = doff - boff; boff = doff; if (gc_pwrite64(fd, &phdr, sizeof (phdr), poff) != 0) goto err; poff += sizeof (phdr); #endif /* _LP64 */ } /* * Construct the headers for each mapping and write out its data * if the content parameter indicates that it should be present * in the core file. */ if (Pmapping_iter(P, dump_map, &pgc) != 0) goto err; if (dump_sections(&pgc) != 0) goto err; if (write_shstrtab(P, &pgc) != 0) goto err; free(pgc.pgc_chunk); return (0); err: /* * Wipe out anything we may have written if there was an error. */ (void) ftruncate64(fd, 0); free(pgc.pgc_chunk); return (-1); }