coredumper-solaris.cpp revision 802928d04b7a79409eae64021aaa792269b8f29e
af062818b47340eef15700d2f0211576ba3506eevboxsync * IPRT Testcase - Core Dumper.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Copyright (C) 2010 Oracle Corporation
af062818b47340eef15700d2f0211576ba3506eevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
af062818b47340eef15700d2f0211576ba3506eevboxsync * available from http://www.virtualbox.org. This file is free software;
af062818b47340eef15700d2f0211576ba3506eevboxsync * you can redistribute it and/or modify it under the terms of the GNU
af062818b47340eef15700d2f0211576ba3506eevboxsync * General Public License (GPL) as published by the Free Software
af062818b47340eef15700d2f0211576ba3506eevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
af062818b47340eef15700d2f0211576ba3506eevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
af062818b47340eef15700d2f0211576ba3506eevboxsync * The contents of this file may alternatively be used under the terms
af062818b47340eef15700d2f0211576ba3506eevboxsync * of the Common Development and Distribution License Version 1.0
af062818b47340eef15700d2f0211576ba3506eevboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * VirtualBox OSE distribution, in which case the provisions of the
af062818b47340eef15700d2f0211576ba3506eevboxsync * CDDL are applicable instead of those of the GPL.
af062818b47340eef15700d2f0211576ba3506eevboxsync * You may elect to license modified versions of this file under the
af062818b47340eef15700d2f0211576ba3506eevboxsync * terms and conditions of either the GPL or the CDDL or both.
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Header Files *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync#endif /* RT_OS_SOLARIS */
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsyncvolatile static uint64_t g_CoreDumpThread = NIL_RTTHREAD;
af062818b47340eef15700d2f0211576ba3506eevboxsyncvolatile static bool g_fCoreDumpSignalSetup = false;
af062818b47340eef15700d2f0211576ba3506eevboxsyncvolatile static bool g_fCoreDumpDeliberate = false;
af062818b47340eef15700d2f0211576ba3506eevboxsyncvolatile static bool g_fCoreDumpInProgress = false;
af062818b47340eef15700d2f0211576ba3506eevboxsync/*******************************************************************************
af062818b47340eef15700d2f0211576ba3506eevboxsync* Defined Constants And Macros *
af062818b47340eef15700d2f0211576ba3506eevboxsync*******************************************************************************/
af062818b47340eef15700d2f0211576ba3506eevboxsync } while (0)
af062818b47340eef15700d2f0211576ba3506eevboxsync * ELFNOTEHDR: ELF NOTE header.
af062818b47340eef15700d2f0211576ba3506eevboxsynctypedef struct ELFNOTEHDR
af062818b47340eef15700d2f0211576ba3506eevboxsync * Wrapper function to write IPRT format style string to the syslog.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pszFormat Format string
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic void rtCoreDumperSysLogWrapper(const char *pszFormat, ...)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Determines endianness of the system. Just for completeness.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return Will return false if system is little endian, true otherwise.
af062818b47340eef15700d2f0211576ba3506eevboxsync const int i = 1;
af062818b47340eef15700d2f0211576ba3506eevboxsync char *p = (char *)&i;
af062818b47340eef15700d2f0211576ba3506eevboxsync if (p[0] == 1)
af062818b47340eef15700d2f0211576ba3506eevboxsync return false;
af062818b47340eef15700d2f0211576ba3506eevboxsync return true;
af062818b47340eef15700d2f0211576ba3506eevboxsync * Reads from a file making sure an interruption doesn't cause a failure.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param hFile Handle to the file to read.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pv Where to store the read data.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param cbToRead Size of data to read.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int ReadFileNoIntr(RTFILE hFile, void *pv, size_t cbToRead)
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = RTFileRead(hFile, pv, cbToRead, NULL /* Read all */);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Writes to a file making sure an interruption doesn't cause a failure.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param hFile Handle to the file to write.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pv Pointer to what to write.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param cbToRead Size of data to write.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int WriteFileNoIntr(RTFILE hFile, const void *pcv, size_t cbToRead)
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = RTFileWrite(hFile, pcv, cbToRead, NULL /* Write all */);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read from a given offet in the process' address space.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxProc Pointer to the VBox process.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pv Where to read the data into.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param cb Size of the read buffer.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param off Offset to read from.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return VINF_SUCCESS, if all the given bytes was read in, otherwise VERR_READ_ERROR.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic ssize_t ProcReadAddrSpace(PVBOXPROCESS pVBoxProc, RTFOFF off, void *pvBuf, size_t cbToRead)
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileReadAt(pVBoxProc->hAs, off, pvBuf, cbToRead, NULL);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Determines if the current process' architecture is suitable for dumping core.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxProc Pointer to the VBox process.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return true if the architecture matches the current one.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic inline bool IsProcessArchNative(PVBOXPROCESS pVBoxProc)
af062818b47340eef15700d2f0211576ba3506eevboxsync return pVBoxProc->ProcInfo.pr_dmodel == PR_MODEL_NATIVE;
af062818b47340eef15700d2f0211576ba3506eevboxsync * Helper function to get the size of a file given it's path.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pszPath Pointer to the full path of the file.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return The size of the file in bytes.
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileOpen(&hFile, pszPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "GetFileSize failed to open %s rc=%Rrc\n", pszPath, rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Pre-compute and pre-allocate sufficient memory for dumping core.
af062818b47340eef15700d2f0211576ba3506eevboxsync * This is meant to be called once, as a single-large anonymously
af062818b47340eef15700d2f0211576ba3506eevboxsync * mapped memory area which will be used during the core dumping routines.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertReturn(pVBoxCore->pvCore == NULL, VERR_ALREADY_EXISTS);
af062818b47340eef15700d2f0211576ba3506eevboxsync size_t cbAccounting; /* Size of each accounting entry per entry */
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/map", 0, sizeof(prmap_t), sizeof(VBOXSOLMAPINFO) },
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/auxv", 0, 0, 0 },
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/lpsinfo", sizeof(prheader_t), sizeof(lwpsinfo_t), sizeof(VBOXSOLTHREADINFO) },
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/lstatus", 0, 0, 0 },
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/ldt", 0, 0, 0 },
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/cred", sizeof(prcred_t), sizeof(gid_t), 0 },
af062818b47340eef15700d2f0211576ba3506eevboxsync { "/proc/%d/priv", sizeof(prpriv_t), sizeof(priv_chunk_t), 0 },
af062818b47340eef15700d2f0211576ba3506eevboxsync for (int i = 0; i < (int)RT_ELEMENTS(aPreAllocTable); i++)
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), aPreAllocTable[i].pszFilePath, (int)pVBoxCore->VBoxProc.Process);
af062818b47340eef15700d2f0211576ba3506eevboxsync cb += ((cbFile - aPreAllocTable[i].cbHeader) / aPreAllocTable[i].cbEntry) * (aPreAllocTable[i].cbAccounting > 0 ?
af062818b47340eef15700d2f0211576ba3506eevboxsync * Make room for our own mapping accountant entry which will also be included in the core.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Allocate the required space, plus some extra room.
af062818b47340eef15700d2f0211576ba3506eevboxsync void *pv = mmap(NULL, cb, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1 /* fd */, 0 /* offset */);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "AllocMemoryArea: memory area of %u bytes allocated.\n", cb));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "AllocMemoryArea: failed cb=%u\n", cb));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Free memory area used by the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "FreeMemoryArea: memory area of %u bytes freed.\n", pVBoxCore->cbCore));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Get a chunk from the area of allocated memory.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param cb Size of requested chunk.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return Pointer to allocated memory, or NULL on failure.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic void *GetMemoryChunk(PVBOXCORE pVBoxCore, size_t cb)
af062818b47340eef15700d2f0211576ba3506eevboxsync size_t cbAllocated = (char *)pVBoxCore->pvFree - (char *)pVBoxCore->pvCore;
af062818b47340eef15700d2f0211576ba3506eevboxsync * Reads the proc file's content into a newly allocated buffer.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pszFileFmt Only the name of the file to read from (/proc/<pid> will be prepended)
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param ppv Where to store the allocated buffer.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pcb Where to store size of the buffer.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int ProcReadFileInto(PVBOXCORE pVBoxCore, const char *pszProcFileName, void **ppv, size_t *pcb)
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/%s", (int)pVBoxCore->VBoxProc.Process, pszProcFileName);
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync *pcb = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadFileInto: failed to open %s. rc=%Rrc\n", szPath, rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read process information (format psinfo_t) from /proc.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/psinfo", (int)pVBoxProc->Process);
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = ReadFileNoIntr(hFile, &pVBoxProc->ProcInfo, cbProcInfo);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read process status (format pstatus_t) from /proc.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/status", (int)pVBoxProc->Process);
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertCompile(sizeof(pstatus_t) == sizeof(pVBoxProc->ProcStatus));
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = ReadFileNoIntr(hFile, &pVBoxProc->ProcStatus, cbProcStatus);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read process credential information (format prcred_t + array of guid_t)
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @remarks Should not be called before successful call to @see AllocMemoryArea()
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync return ProcReadFileInto(pVBoxCore, "cred", &pVBoxProc->pvCred, &pVBoxProc->cbCred);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read process privilege information (format prpriv_t + array of priv_chunk_t)
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @remarks Should not be called before successful call to @see AllocMemoryArea()
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = ProcReadFileInto(pVBoxCore, "priv", (void **)&pVBoxProc->pPriv, &pVBoxProc->cbPriv);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadPriv: getprivimplinfo returned NULL.\n"));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read process LDT information (format array of struct ssd) from /proc.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxProc Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @remarks Should not be called before successful call to @see AllocMemoryArea()
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync return ProcReadFileInto(pVBoxCore, "ldt", &pVBoxProc->pvLdt, &pVBoxProc->cbLdt);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read process auxiliary vectors (format auxv_t) for the process.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @remarks Should not be called before successful call to @see AllocMemoryArea()
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/auxv", (int)pVBoxProc->Process);
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: RTFileOpen %s failed rc=%Rrc\n", szPath, rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync size_t cbAuxFile = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->pAuxVecs = (auxv_t*)GetMemoryChunk(pVBoxCore, cbAuxFile + sizeof(auxv_t));
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = ReadFileNoIntr(hFile, pVBoxProc->pAuxVecs, cbAuxFile);
af062818b47340eef15700d2f0211576ba3506eevboxsync /* Terminate list of vectors */
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "ProcReadAuxVecs: cbAuxFile=%u auxv_t size %d cAuxVecs=%u\n", cbAuxFile, sizeof(auxv_t), pVBoxProc->cAuxVecs));
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->pAuxVecs[pVBoxProc->cAuxVecs].a_type = AT_NULL;
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->pAuxVecs[pVBoxProc->cAuxVecs].a_un.a_val = 0L;
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: Invalid vector count %u\n", pVBoxProc->cAuxVecs));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: ReadFileNoIntr failed. rc=%Rrc cbAuxFile=%u\n", rc, cbAuxFile));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: no memory for %u bytes\n", cbAuxFile + sizeof(auxv_t)));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadAuxVecs: aux file too small %u, expecting %u or more\n", cbAuxFile, sizeof(auxv_t)));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Find an element in the process' auxiliary vector.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic long GetAuxVal(PVBOXPROCESS pVBoxProc, int Type)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read the process mappings (format prmap_t array).
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @remarks Should not be called before successful call to @see AllocMemoryArea()
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/map", (int)pVBoxProc->Process);
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = RTFileOpen(&hFile, szPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/as", (int)pVBoxProc->Process);
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = RTFileOpen(&pVBoxProc->hAs, szPath, RTFILE_O_OPEN | RTFILE_O_READ);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Allocate and read all the prmap_t objects from proc.
af062818b47340eef15700d2f0211576ba3506eevboxsync size_t cbMapFile = u64Size < ~(size_t)0 ? u64Size : ~(size_t)0;
af062818b47340eef15700d2f0211576ba3506eevboxsync prmap_t *pMap = (prmap_t*)GetMemoryChunk(pVBoxCore, cbMapFile);
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->cMappings = cbMapFile / sizeof(prmap_t);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Allocate for each prmap_t object, a corresponding VBOXSOLMAPINFO object.
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->pMapInfoHead = (PVBOXSOLMAPINFO)GetMemoryChunk(pVBoxCore, pVBoxProc->cMappings * sizeof(VBOXSOLMAPINFO));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Associate the prmap_t with the mapping info object.
af062818b47340eef15700d2f0211576ba3506eevboxsync for (uint64_t i = 0; i < pVBoxProc->cMappings; i++, pMap++, pCur++)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Make sure we can read the mapping, otherwise mark them to be skipped.
af062818b47340eef15700d2f0211576ba3506eevboxsync size_t cb = RT_MIN(sizeof(achBuf), pCur->pMap.pr_size - k);
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc2 = ProcReadAddrSpace(pVBoxProc, pCur->pMap.pr_vaddr + k, &achBuf, cb);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: skipping mapping. vaddr=%#x rc=%Rrc\n", pCur->pMap.pr_vaddr, rc2));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Instead of storing the actual mapping data which we failed to read, the core
af062818b47340eef15700d2f0211576ba3506eevboxsync * will contain an errno in place. So we adjust the prmap_t's size field too
af062818b47340eef15700d2f0211576ba3506eevboxsync * so the program header offsets match.
af062818b47340eef15700d2f0211576ba3506eevboxsync if (pCur->fError == 0) /* huh!? somehow errno got reset? fake one! EFAULT is nice. */
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "ProcReadMappings: successfully read in %u mappings\n", pVBoxProc->cMappings));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: GetMemoryChunk failed %u\n", pVBoxProc->cMappings * sizeof(VBOXSOLMAPINFO)));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: Invalid mapping count %u\n", pVBoxProc->cMappings));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: FileReadNoIntr failed. rc=%Rrc cbMapFile=%u\n", rc, cbMapFile));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: GetMemoryChunk failed. cbMapFile=%u\n", cbMapFile));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMappings: failed to open %s. rc=%Rrc\n", szPath, rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Reads the thread information for all threads in the process.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @remarks Should not be called before successful call to @see AllocMemoryArea()
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertReturn(pVBoxProc->pCurThreadCtx, VERR_NO_DATA);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read the information for threads.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Format: prheader_t + array of lwpsinfo_t's.
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = ProcReadFileInto(pVBoxCore, "lpsinfo", &pvInfoHdr, &cbInfoHdrAndData);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read the status of threads.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Format: prheader_t + array of lwpstatus_t's.
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = ProcReadFileInto(pVBoxCore, "lstatus", &pvStatusHdr, &cbStatusHdrAndData);
af062818b47340eef15700d2f0211576ba3506eevboxsync prheader_t *pStatusHdr = (prheader_t *)pvStatusHdr;
af062818b47340eef15700d2f0211576ba3506eevboxsync lwpstatus_t *pStatus = (lwpstatus_t *)((uintptr_t)pStatusHdr + sizeof(prheader_t));
af062818b47340eef15700d2f0211576ba3506eevboxsync lwpsinfo_t *pInfo = (lwpsinfo_t *)((uintptr_t)pInfoHdr + sizeof(prheader_t));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "ProcReadThreads: read info(%u) status(%u), threads:cInfo=%u cStatus=%u\n", cbInfoHdrAndData,
af062818b47340eef15700d2f0211576ba3506eevboxsync * Minor sanity size check (remember sizeof lwpstatus_t & lwpsinfo_t is <= size in file per entry).
af062818b47340eef15700d2f0211576ba3506eevboxsync if ( (cbStatusHdrAndData - sizeof(prheader_t)) % pStatusHdr->pr_entsize == 0
af062818b47340eef15700d2f0211576ba3506eevboxsync && (cbInfoHdrAndData - sizeof(prheader_t)) % pInfoHdr->pr_entsize == 0)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Make sure we have a matching lstatus entry for an lpsinfo entry unless
af062818b47340eef15700d2f0211576ba3506eevboxsync * it is a zombie thread, in which case we will not have a matching lstatus entry.
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: cStatus = %u pStatuslwpid=%d infolwpid=%d\n", cStatus,
af062818b47340eef15700d2f0211576ba3506eevboxsync pStatus = (lwpstatus_t *)((uintptr_t)pStatus + pStatusHdr->pr_entsize);
af062818b47340eef15700d2f0211576ba3506eevboxsync pInfo = (lwpsinfo_t *)((uintptr_t)pInfo + pInfoHdr->pr_entsize);
af062818b47340eef15700d2f0211576ba3506eevboxsync * Threre can still be more lwpsinfo_t's than lwpstatus_t's, build the
af062818b47340eef15700d2f0211576ba3506eevboxsync * lists accordingly.
af062818b47340eef15700d2f0211576ba3506eevboxsync pStatus = (lwpstatus_t *)((uintptr_t)pStatusHdr + sizeof(prheader_t));
af062818b47340eef15700d2f0211576ba3506eevboxsync pInfo = (lwpsinfo_t *)((uintptr_t)pInfoHdr + sizeof(prheader_t));
af062818b47340eef15700d2f0211576ba3506eevboxsync size_t cbThreadInfo = RT_MAX(cStatus, cInfo) * sizeof(VBOXSOLTHREADINFO);
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->pThreadInfoHead = (PVBOXSOLTHREADINFO)GetMemoryChunk(pVBoxCore, cbThreadInfo);
af062818b47340eef15700d2f0211576ba3506eevboxsync PVBOXSOLTHREADINFO pCur = pVBoxProc->pThreadInfoHead;
af062818b47340eef15700d2f0211576ba3506eevboxsync * Adjust the context of the dumping thread to reflect the context
af062818b47340eef15700d2f0211576ba3506eevboxsync * when the core dump got initiated before whatever signal caused it.
af062818b47340eef15700d2f0211576ba3506eevboxsync && pStatus->pr_lwpid == (id_t)pVBoxProc->hCurThread)
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertCompile(sizeof(pStatus->pr_reg) == sizeof(pVBoxProc->pCurThreadCtx->uc_mcontext.gregs));
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertCompile(sizeof(pStatus->pr_fpreg) == sizeof(pVBoxProc->pCurThreadCtx->uc_mcontext.fpregs));
af062818b47340eef15700d2f0211576ba3506eevboxsync memcpy(&pStatus->pr_reg, &pVBoxProc->pCurThreadCtx->uc_mcontext.gregs, sizeof(pStatus->pr_reg));
af062818b47340eef15700d2f0211576ba3506eevboxsync memcpy(&pStatus->pr_fpreg, &pVBoxProc->pCurThreadCtx->uc_mcontext.fpregs, sizeof(pStatus->pr_fpreg));
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertCompile(sizeof(pStatus->pr_lwphold) == sizeof(pVBoxProc->pCurThreadCtx->uc_sigmask));
af062818b47340eef15700d2f0211576ba3506eevboxsync memcpy(&pStatus->pr_lwphold, &pVBoxProc->pCurThreadCtx->uc_sigmask, sizeof(pStatus->pr_lwphold));
af062818b47340eef15700d2f0211576ba3506eevboxsync pStatus->pr_ustack = (uintptr_t)&pVBoxProc->pCurThreadCtx->uc_stack;
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "ProcReadThreads: patched dumper thread context with pre-dump time context.\n"));
af062818b47340eef15700d2f0211576ba3506eevboxsync pStatus = (lwpstatus_t *)((uintptr_t)pStatus + pStatusHdr->pr_entsize);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: missing status for lwp %d\n", pInfo->pr_lwpid));
af062818b47340eef15700d2f0211576ba3506eevboxsync pInfo = (lwpsinfo_t *)((uintptr_t)pInfo + pInfoHdr->pr_entsize);
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME "ProcReadThreads: successfully read %u threads.\n", cInfo));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: GetMemoryChunk failed for %u bytes\n", cbThreadInfo));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: Invalid state information for threads.\n", rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: huh!? cbStatusHdrAndData=%u prheader_t=%u entsize=%u\n", cbStatusHdrAndData,
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: huh!? cbInfoHdrAndData=%u entsize=%u\n", cbInfoHdrAndData, pStatusHdr->pr_entsize));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: ReadFileNoIntr failed for \"lpsinfo\" rc=%Rrc\n", rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadThreads: ReadFileNoIntr failed for \"lstatus\" rc=%Rrc\n", rc));
af062818b47340eef15700d2f0211576ba3506eevboxsync * Reads miscellaneous information that is collected as part of a core file.
af062818b47340eef15700d2f0211576ba3506eevboxsync * This may include platform name, zone name and other OS-specific information.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read the platform name, uname string and zone name.
af062818b47340eef15700d2f0211576ba3506eevboxsync int rc = sysinfo(SI_PLATFORM, pVBoxProc->szPlatform, sizeof(pVBoxProc->szPlatform));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: sysinfo failed. rc=%d errno=%d\n", rc, errno));
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->szPlatform[sizeof(pVBoxProc->szPlatform) - 1] = '\0';
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: uname failed. rc=%d errno=%d\n", rc, errno));
af062818b47340eef15700d2f0211576ba3506eevboxsync rc = getzonenamebyid(pVBoxProc->ProcInfo.pr_zoneid, pVBoxProc->szZoneName, sizeof(pVBoxProc->szZoneName));
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: getzonenamebyid failed. rc=%d errno=%d zoneid=%d\n", rc, errno, pVBoxProc->ProcInfo.pr_zoneid));
af062818b47340eef15700d2f0211576ba3506eevboxsync pVBoxProc->szZoneName[sizeof(pVBoxProc->szZoneName) - 1] = '\0';
af062818b47340eef15700d2f0211576ba3506eevboxsync * On Solaris use the old-style procfs interfaces but the core file still should have this
af062818b47340eef15700d2f0211576ba3506eevboxsync * info. for backward and GDB compatibility, hence the need for this ugly function.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pInfo Pointer to the old prpsinfo_t structure to update.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic void GetOldProcessInfo(PVBOXCORE pVBoxCore, prpsinfo_t *pInfo)
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrCopy(pInfo->pr_clname, sizeof(pInfo->pr_clname), pSrc->pr_lwp.pr_clname);
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrCopy(pInfo->pr_fname, sizeof(pInfo->pr_fname), pSrc->pr_fname);
af062818b47340eef15700d2f0211576ba3506eevboxsync memcpy(&pInfo->pr_psargs, &pSrc->pr_psargs, sizeof(pInfo->pr_psargs));
af062818b47340eef15700d2f0211576ba3506eevboxsync * On Solaris use the old-style procfs interfaces but the core file still should have this
af062818b47340eef15700d2f0211576ba3506eevboxsync * info. for backward and GDB compatibility, hence the need for this ugly function.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pInfo Pointer to the thread info.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pStatus Pointer to the thread status.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pDst Pointer to the old-style status structure to update.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic void GetOldProcessStatus(PVBOXCORE pVBoxCore, lwpsinfo_t *pInfo, lwpstatus_t *pStatus, prstatus_t *pDst)
af062818b47340eef15700d2f0211576ba3506eevboxsync /* PR_PTRACE is never set */
af062818b47340eef15700d2f0211576ba3506eevboxsync pDst->pr_oldcontext = (ucontext_t *)pStatus->pr_oldcontext;
af062818b47340eef15700d2f0211576ba3506eevboxsync memcpy(pDst->pr_reg, pStatus->pr_reg, sizeof(pDst->pr_reg));
af062818b47340eef15700d2f0211576ba3506eevboxsync memcpy(pDst->pr_sysarg, pStatus->pr_sysarg, sizeof(pDst->pr_sysarg));
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrCopy(pDst->pr_clname, sizeof(pDst->pr_clname), pStatus->pr_clname);
af062818b47340eef15700d2f0211576ba3506eevboxsync pDst->pr_sigpend = pVBoxProc->ProcStatus.pr_sigpend;
af062818b47340eef15700d2f0211576ba3506eevboxsync pDst->pr_brkbase = (caddr_t)pVBoxProc->ProcStatus.pr_brkbase;
af062818b47340eef15700d2f0211576ba3506eevboxsync pDst->pr_brksize = pVBoxProc->ProcStatus.pr_brksize;
af062818b47340eef15700d2f0211576ba3506eevboxsync pDst->pr_stkbase = (caddr_t)pVBoxProc->ProcStatus.pr_stkbase;
af062818b47340eef15700d2f0211576ba3506eevboxsync pDst->pr_stksize = pVBoxProc->ProcStatus.pr_stksize;
af062818b47340eef15700d2f0211576ba3506eevboxsync * Callback for rtCoreDumperForEachThread to suspend a thread.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pvThreadInfo Opaque pointer to thread information.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int suspendThread(PVBOXCORE pVBoxCore, void *pvThreadInfo)
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertPtrReturn(pvThreadInfo, VERR_INVALID_POINTER);
af062818b47340eef15700d2f0211576ba3506eevboxsync lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)pvThreadInfo;
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME ":suspendThread %d\n", (lwpid_t)pThreadInfo->pr_lwpid));
af062818b47340eef15700d2f0211576ba3506eevboxsync if ((lwpid_t)pThreadInfo->pr_lwpid != pVBoxCore->VBoxProc.hCurThread)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Callback for rtCoreDumperForEachThread to resume a thread.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pvThreadInfo Opaque pointer to thread information.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int resumeThread(PVBOXCORE pVBoxCore, void *pvThreadInfo)
af062818b47340eef15700d2f0211576ba3506eevboxsync AssertPtrReturn(pvThreadInfo, VERR_INVALID_POINTER);
af062818b47340eef15700d2f0211576ba3506eevboxsync lwpsinfo_t *pThreadInfo = (lwpsinfo_t *)pvThreadInfo;
af062818b47340eef15700d2f0211576ba3506eevboxsync CORELOG((CORELOG_NAME ":resumeThread %d\n", (lwpid_t)pThreadInfo->pr_lwpid));
af062818b47340eef15700d2f0211576ba3506eevboxsync if ((lwpid_t)pThreadInfo->pr_lwpid != (lwpid_t)pVBoxCore->VBoxProc.hCurThread)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Calls a thread worker function for all threads in the process as described by /proc
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pVBoxCore Pointer to the core object.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pcThreads Number of threads read.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @param pfnWorker Callback function for each thread.
af062818b47340eef15700d2f0211576ba3506eevboxsync * @return IPRT status code.
af062818b47340eef15700d2f0211576ba3506eevboxsyncstatic int rtCoreDumperForEachThread(PVBOXCORE pVBoxCore, uint64_t *pcThreads, PFNCORETHREADWORKER pfnWorker)
af062818b47340eef15700d2f0211576ba3506eevboxsync * Read the information for threads.
af062818b47340eef15700d2f0211576ba3506eevboxsync * Format: prheader_t + array of lwpsinfo_t's.
af062818b47340eef15700d2f0211576ba3506eevboxsync RTStrPrintf(szLpsInfoPath, sizeof(szLpsInfoPath), "/proc/%d/lpsinfo", (int)pVBoxProc->Process);
void *pvInfoHdr = mmap(NULL, cbInfoHdrAndData, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1 /* fd */, 0 /* offset */);
if (pvInfoHdr)
if (pcThreads)
return rc;
return rc;
return rc;
CORELOG((CORELOG_NAME "SuspendThreads: Stopped %u threads successfully with %u tries\n", cThreads, cTries));
return rc;
#ifdef RT_OS_SOLARIS
return rc;
switch (enmType)
case enmOldEra:
while (pThreadInfo)
case enmNewEra:
while (pThreadInfo)
return cb;
#ifdef RT_OS_SOLARIS
typedef struct ELFWRITENOTE
const char *pszType;
const void *pcv;
} ELFWRITENOTE;
switch (enmType)
case enmOldEra:
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader failed for %s. rc=%Rrc\n", aElfNotes[i].pszType, rc));
rc = ElfWriteNoteHeader(pVBoxCore, NT_PRFPREG, &pThreadInfo->pStatus->pr_fpreg, sizeof(prfpregset_t));
CORELOGRELSYS((CORELOG_NAME "ElfWriteSegment: ElfWriteNote failed for NT_PRSTATUS. rc=%Rrc\n", rc));
case enmNewEra:
{ "NT_PRPRIVINFO", NT_PRPRIVINFO, pVBoxProc->pcPrivImpl, PRIV_IMPL_INFO_SIZE(pVBoxProc->pcPrivImpl) },
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader failed for %s. rc=%Rrc\n", aElfNotes[i].pszType, rc));
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader for NT_LWPSINFO failed. rc=%Rrc\n", rc));
CORELOGRELSYS((CORELOG_NAME "ElfWriteNoteSection: ElfWriteNoteHeader for NT_LWPSTATUS failed. rc=%Rrc\n", rc));
return rc;
while (pMapInfo)
uint64_t k = 0;
CORELOGRELSYS((CORELOG_NAME "ElfWriteMappings: Failed to read mapping, can't recover. Bye. rc=%Rrc\n", rc));
return VERR_INVALID_STATE;
return rc;
k += cb;
return rc;
return VINF_SUCCESS;
while (pMapInfo)
ProgHdr.p_vaddr = pMapInfo->pMap.pr_vaddr; /* Virtual address of this mapping in the process address space */
return rc;
return rc;
return VERR_INVALID_STATE;
if (pfnWriter)
goto WriteCoreDone;
rc = RTFileOpen(&pVBoxCore->hCoreFile, pVBoxCore->szCorePath, RTFILE_O_OPEN_CREATE | RTFILE_O_TRUNCATE | RTFILE_O_READWRITE | RTFILE_O_DENY_ALL);
goto WriteCoreDone;
#ifdef RT_ARCH_AMD64
goto WriteCoreDone;
CORELOGRELSYS((CORELOG_NAME "WriteCore: pfnWriter failed writing old-style ELF program Header. rc=%Rrc\n", rc));
goto WriteCoreDone;
CORELOGRELSYS((CORELOG_NAME "WriteCore: pfnWriter failed writing new-style ELF program header. rc=%Rrc\n", rc));
goto WriteCoreDone;
goto WriteCoreDone;
goto WriteCoreDone;
goto WriteCoreDone;
goto WriteCoreDone;
return rc;
RTProcGetExecutableName(pVBoxProc->szExecPath, sizeof(pVBoxProc->szExecPath)); /* this gets full path not just name */
RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s", g_szCoreDumpDir, g_szCoreDumpFile);
CORELOG((CORELOG_NAME "CreateCore: Taking Core %s from Thread %d\n", pVBoxCore->szCorePath, (int)pVBoxProc->hCurThread));
* Read process status, information such as number of active LWPs will be invalid since we just quiesced the process.
struct COREACCUMULATOR
const char *pszName;
bool fOptional;
} aAccumulators[] =
return VINF_SUCCESS;
return rc;
return VERR_INVALID_STATE;
return VINF_SUCCESS;
if (!pContext)
return VERR_INVALID_POINTER;
CORELOGRELSYS((CORELOG_NAME "TakeDump: WriteCore failed. szCorePath=%s rc=%Rrc\n", VBoxCore.szCorePath, rc));
return rc;
bool fCallSystemDump = false;
CORELOGRELSYS((CORELOG_NAME "SignalHandler: Core dumper (thread %u) crashed Sig=%d. Triggering system dump\n",
fCallSystemDump = true;
CORELOGRELSYS((CORELOG_NAME "SignalHandler: Core dump already in progress! Waiting a while for completion Sig=%d.\n", Sig));
if (iTimeout <= 0)
if (iTimeout <= 0)
fCallSystemDump = true;
CORELOGRELSYS((CORELOG_NAME "SignalHandler: Core dumper seems to be stuck. Signalling new signal %d\n", Sig));
if (fCallSystemDump)
abort();
return VERR_WRONG_ORDER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (pszOutputFile)
if (fLiveCore == false)
return VINF_SUCCESS;
if (pszOutputDir)
return VINF_SUCCESS;
return VINF_SUCCESS;