VirtualBox

Changeset 32422 in vbox


Ignore:
Timestamp:
Sep 10, 2010 4:48:22 PM (14 years ago)
Author:
vboxsync
Message:

Runtime/r3/coredumper: addressed remaining todos in r65763.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp

    r32413 r32422  
    5353# include <sys/systeminfo.h>
    5454# include <sys/mman.h>
     55# include <ucontext.h>
    5556#endif  /* RT_OS_SOLARIS */
    5657
     
    6364static RTNATIVETHREAD volatile  g_CoreDumpThread             = NIL_RTNATIVETHREAD;
    6465static bool volatile            g_fCoreDumpSignalSetup       = false;
    65 static bool volatile            g_fCoreDumpDeliberate        = false;
    6666static uint32_t volatile        g_fCoreDumpFlags             = 0;
    6767static char                     g_szCoreDumpDir[PATH_MAX]    = { 0 };
     
    12751275    {
    12761276        CORELOGRELSYS((CORELOG_NAME "rtCoreDumperSuspendThreads: possible thread bomb!?\n"));
    1277         rc = VERR_GENERAL_FAILURE;   /* @todo better error code */
     1277        rc = VERR_TIMEOUT;
    12781278    }
    12791279    return rc;
     
    19291929 * @param pVBoxCore         Pointer to a core object.
    19301930 * @param pContext          Pointer to the caller context thread.
     1931 * @param pszCoreFilePath   Path to the core file (Optional, can be NULL).
    19311932 *
    19321933 * @remarks Halts all threads.
    19331934 * @return IPRT status code.
    19341935 */
    1935 static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext)
     1936static int rtCoreDumperCreateCore(PVBOXCORE pVBoxCore, ucontext_t *pContext, const char *pszCoreFilePath)
    19361937{
    19371938    AssertReturn(pVBoxCore, VERR_INVALID_POINTER);
     
    19581959
    19591960    /*
    1960      * If no output directory is specified, use current directory.
    1961      */
    1962     if (g_szCoreDumpDir[0] == '\0')
    1963         g_szCoreDumpDir[0] = '.';
    1964 
    1965     if (g_szCoreDumpFile[0] == '\0')
    1966     {
    1967         /* We cannot call RTPathAbs*() as they call getcwd() which calls malloc. */
    1968         RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s.%d",
    1969                     g_szCoreDumpDir, pVBoxProc->pszExecName, (int)pVBoxProc->Process);
     1961     * If a path has been specified, use it. Otherwise use the global path.
     1962     */
     1963    if (!pszCoreFilePath)
     1964    {
     1965        /*
     1966         * If no output directory is specified, use current directory.
     1967         */
     1968        if (g_szCoreDumpDir[0] == '\0')
     1969            g_szCoreDumpDir[0] = '.';
     1970
     1971        if (g_szCoreDumpFile[0] == '\0')
     1972        {
     1973            /* We cannot call RTPathAbs*() as they call getcwd() which calls malloc. */
     1974            RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s.%d",
     1975                        g_szCoreDumpDir, pVBoxProc->pszExecName, (int)pVBoxProc->Process);
     1976        }
     1977        else
     1978            RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s", g_szCoreDumpDir, g_szCoreDumpFile);
    19701979    }
    19711980    else
    1972         RTStrPrintf(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), "%s/core.vb.%s", g_szCoreDumpDir, g_szCoreDumpFile);
     1981        RTStrCopy(pVBoxCore->szCorePath, sizeof(pVBoxCore->szCorePath), pszCoreFilePath);
    19731982
    19741983    CORELOG((CORELOG_NAME  "CreateCore: Taking Core %s from Thread %d\n", pVBoxCore->szCorePath, (int)pVBoxProc->hCurThread));
     
    20812090 *
    20822091 * @param   pContext            The context of the caller.
     2092 * @param   pszOutputFile       Path of the core file. If NULL is passed, the
     2093 *                              global path passed in RTCoreDumperSetup will
     2094 *                              be used.
    20832095 * @returns IPRT status code.
    20842096 */
    2085 static int rtCoreDumperTakeDump(ucontext_t *pContext)
     2097static int rtCoreDumperTakeDump(ucontext_t *pContext, const char *pszOutputFile)
    20862098{
    20872099    if (!pContext)
     
    20982110    VBOXCORE VBoxCore;
    20992111    RT_ZERO(VBoxCore);
    2100     int rc = rtCoreDumperCreateCore(&VBoxCore, pContext);
     2112    int rc = rtCoreDumperCreateCore(&VBoxCore, pContext, pszOutputFile);
    21012113    if (RT_SUCCESS(rc))
    21022114    {
     
    21352147    if (fRc)
    21362148    {
    2137         rc = rtCoreDumperTakeDump((ucontext_t *)pvArg);
     2149        rc = rtCoreDumperTakeDump((ucontext_t *)pvArg, NULL /* Use Global Core filepath */);
    21382150        ASMAtomicWriteHandle(&g_CoreDumpThread, NIL_RTNATIVETHREAD);
    21392151
     
    22152227RTDECL(int) RTCoreDumperTakeDump(const char *pszOutputFile, bool fLiveCore)
    22162228{
    2217     /** @todo r=bird: No setup should be required for this call and it
    2218      * shouldn't change the globals.
    2219      *
    2220      * Would probably be best to serialize RTCoreDumperTakeDump callers using a
    2221      * lazily initialized critsect (see RTOnce) and use different globals to
    2222      * communicate with the signal handlers.
    2223      *
    2224      * Another improvement is to use getcontext() to get the thread context and
    2225      * call rtCoreDumperTakeDump directly.  Extend rtCoreDumperTakeDump so that
    2226      * it takes pszOutputFile as an optional argument.  Mask the other fatal +
    2227      * SIGUSR2 while doing this.
    2228      */
    2229 
    2230     /*
    2231      * Validate input.
    2232      */
    2233     if (ASMAtomicReadBool(&g_fCoreDumpSignalSetup) == false)
    2234         return VERR_WRONG_ORDER;
    2235 
    2236     uint32_t fFlags = ASMAtomicReadU32(&g_fCoreDumpFlags);
    2237     if (fLiveCore && !(fFlags & RTCOREDUMPER_FLAGS_LIVE_CORE))
    2238         return VERR_INVALID_PARAMETER;
    2239 
    2240     if (!fLiveCore && !(fFlags & RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP))
    2241         return VERR_INVALID_PARAMETER;
    2242 
    2243     RT_ZERO(g_szCoreDumpFile);
    2244     if (pszOutputFile)
    2245         RTStrCopy(g_szCoreDumpFile, sizeof(g_szCoreDumpFile), pszOutputFile);
    2246 
    2247     ASMAtomicWriteBool(&g_fCoreDumpDeliberate, true);
    2248 
    2249     if (fLiveCore == false)
    2250         raise(SIGSEGV);
     2229    ucontext_t Context;
     2230    int rc = getcontext(&Context);
     2231    if (!rc)
     2232    {
     2233        /*
     2234         * Block SIGSEGV and co. while we write the core.
     2235         */
     2236        sigset_t SigSet, OldSigSet;
     2237        sigemptyset(&SigSet);
     2238        sigaddset(&SigSet, SIGSEGV);
     2239        sigaddset(&SigSet, SIGBUS);
     2240        sigaddset(&SigSet, SIGTRAP);
     2241        sigaddset(&SigSet, SIGUSR2);
     2242        pthread_sigmask(SIG_BLOCK, &SigSet, &OldSigSet);
     2243        rc = rtCoreDumperTakeDump(&Context, pszOutputFile);
     2244        if (!fLiveCore)
     2245        {
     2246            signal(SIGSEGV, SIG_DFL);
     2247            signal(SIGBUS, SIG_DFL);
     2248            signal(SIGTRAP, SIG_DFL);
     2249            if (RT_SUCCESS(rc))
     2250                raise(SIGKILL);
     2251            else
     2252                abort();
     2253        }
     2254        pthread_sigmask(SIG_SETMASK, &OldSigSet, NULL);
     2255    }
    22512256    else
    2252         raise(SIGUSR2);
    2253 
    2254     ASMAtomicWriteBool(&g_fCoreDumpDeliberate, false);
    2255     return VINF_SUCCESS;
     2257    {
     2258        CORELOGRELSYS(("RTCoreDumperTakeDump: getcontext failed rc=%d.\n"));
     2259        rc = VERR_INVALID_CONTEXT;
     2260    }
     2261
     2262    return rc;
    22562263}
    22572264
     
    22672274                 VERR_INVALID_PARAMETER);
    22682275
    2269 /** @todo r=bird: The idea here was that we shouldn't register the handler
    2270  *        more than once.  I.e. skip it if g_fCoreDumpSignalSetup and the
    2271  *        flags didn't change in any way.  The rational/usecase is that that
    2272  *        allows the user to chain handlers before our SIGSEGV/SIGBUS/SIGTRAP
    2273  *        core dumping + crashing handler.  Since we're registering our stuff
    2274  *        in Main somewhere it's important that only the first call messes with
    2275  *        the signal handlers.  The front end could for instance do a
    2276  *        RTCoreDumperSetup(NULL, RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP |
    2277  *        RTCOREDUMPER_FLAGS_LIVE_CORE) call in it's main() before setting up
    2278  *        it's own SIGBUS/SIGSEGV/SIGTRAP handlers.
    2279  *
    2280  *        Adding the conditional registration via the two flags complicates
    2281  *        the implementation of this use case. */
    2282 
    2283     /*
    2284      * Install core dump signal handler.
     2276    /*
     2277     * Install core dump signal handler only if the flags changed or if it's the first time.
    22852278     */
    22862279    if (   ASMAtomicReadBool(&g_fCoreDumpSignalSetup) == false
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette