VirtualBox

Changeset 62096 in vbox for trunk/src


Ignore:
Timestamp:
Jul 7, 2016 9:03:59 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
108570
Message:

Runtime/r3/solaris: Fix coredumper to workaround psinfo_t structure layout differences across known Solaris versions.

Location:
trunk/src/VBox/Runtime/r3/solaris
Files:
2 edited

Legend:

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

    r58171 r62096  
    232232static inline bool IsProcessArchNative(PRTSOLCOREPROCESS pSolProc)
    233233{
    234     return pSolProc->ProcInfo.pr_dmodel == PR_MODEL_NATIVE;
     234    psinfo_t *pProcInfo = (psinfo_t *)pSolProc->pvProcInfo;
     235    return pProcInfo->pr_dmodel == PR_MODEL_NATIVE;
    235236}
    236237
     
    301302    } const s_aPreAllocTable[] =
    302303    {
     304        { "/proc/%d/psinfo",     0,                  0,                     0 },
    303305        { "/proc/%d/map",        0,                  sizeof(prmap_t),       sizeof(RTSOLCOREMAPINFO) },
    304306        { "/proc/%d/auxv",       0,                  0,                     0 },
     
    456458
    457459    PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
    458     char szPath[PATH_MAX];
    459     int rc = VINF_SUCCESS;
    460 
    461     RTStrPrintf(szPath, sizeof(szPath), "/proc/%d/psinfo", (int)pSolProc->Process);
    462     int fd = open(szPath, O_RDONLY);
    463     if (fd >= 0)
    464     {
    465         size_t cbProcInfo = sizeof(psinfo_t);
    466         rc = ReadFileNoIntr(fd, &pSolProc->ProcInfo, cbProcInfo);
    467         close(fd);
    468     }
    469     else
    470     {
    471         rc = RTErrConvertFromErrno(fd);
    472         CORELOGRELSYS((CORELOG_NAME "ProcReadInfo: failed to open %s. rc=%Rrc\n", szPath, rc));
    473     }
    474 
    475     return rc;
     460    return ProcReadFileInto(pSolCore, "psinfo", &pSolProc->pvProcInfo, &pSolProc->cbProcInfo);
    476461}
    477462
     
    993978    }
    994979
    995     rc = getzonenamebyid(pSolProc->ProcInfo.pr_zoneid, pSolProc->szZoneName, sizeof(pSolProc->szZoneName));
     980    /*
     981     * See comment in GetOldProcessInfo() for why we need to verify the offset here.
     982     * It's not perfect, but it should be fine unless they really mess up the structure
     983     * layout in the future. See @bugref{8479}.
     984     */
     985    size_t const offZoneId = RT_OFFSETOF(psinfo_t, pr_zoneid);
     986    if (pSolProc->cbProcInfo < offZoneId)
     987    {
     988        CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: psinfo size mismatch. cbProcInfo=%u expected >= %u\n",
     989                       pSolProc->cbProcInfo, offZoneId));
     990        return VERR_GENERAL_FAILURE;
     991    }
     992
     993    psinfo_t *pProcInfo = (psinfo_t *)pSolProc->pvProcInfo;
     994    rc = getzonenamebyid(pProcInfo->pr_zoneid, pSolProc->szZoneName, sizeof(pSolProc->szZoneName));
    996995    if (rc < 0)
    997996    {
    998997        CORELOGRELSYS((CORELOG_NAME "ProcReadMiscInfo: getzonenamebyid failed. rc=%d errno=%d zoneid=%d\n", rc, errno,
    999                        pSolProc->ProcInfo.pr_zoneid));
     998                       pProcInfo->pr_zoneid));
    1000999        return VERR_GENERAL_FAILURE;
    10011000    }
     
    10141013 * info. for backward and GDB compatibility, hence the need for this ugly function.
    10151014 *
     1015 * @returns IPRT status code.
     1016 *
    10161017 * @param pSolCore          Pointer to the core object.
    10171018 * @param pInfo             Pointer to the old prpsinfo_t structure to update.
    10181019 */
    1019 static void GetOldProcessInfo(PRTSOLCORE pSolCore, prpsinfo_t *pInfo)
    1020 {
    1021     AssertReturnVoid(pSolCore);
    1022     AssertReturnVoid(pInfo);
    1023 
     1020static int GetOldProcessInfo(PRTSOLCORE pSolCore, prpsinfo_t *pInfo)
     1021{
     1022    AssertReturn(pSolCore, VERR_INVALID_PARAMETER);
     1023    AssertReturn(pInfo,    VERR_INVALID_PARAMETER);
     1024
     1025    /*
     1026     * The psinfo_t and the size of /proc/<pid>/psinfo varies both within the same Solaris system
     1027     * and across Solaris major versions. However, manual dumping of the structure and offsets shows
     1028     * that they changed the size of lwpsinfo_t and the size of the lwpsinfo_t::pr_filler.
     1029     *
     1030     * The proc psinfo file will be what gets dumped ultimately in the core file but we still need
     1031     * to read the fields to translate to the older process info structure here.
     1032     *
     1033     * See @bugref{8479}.
     1034     */
    10241035    PRTSOLCOREPROCESS pSolProc = &pSolCore->SolProc;
    1025     psinfo_t *pSrc = &pSolProc->ProcInfo;
    1026     memset(pInfo, 0, sizeof(prpsinfo_t));
    1027     pInfo->pr_state    = pSrc->pr_lwp.pr_state;
    1028     pInfo->pr_zomb     = (pInfo->pr_state == SZOMB);
    1029     RTStrCopy(pInfo->pr_clname, sizeof(pInfo->pr_clname), pSrc->pr_lwp.pr_clname);
    1030     RTStrCopy(pInfo->pr_fname, sizeof(pInfo->pr_fname), pSrc->pr_fname);
    1031     memcpy(&pInfo->pr_psargs, &pSrc->pr_psargs, sizeof(pInfo->pr_psargs));
    1032     pInfo->pr_nice     = pSrc->pr_lwp.pr_nice;
    1033     pInfo->pr_flag     = pSrc->pr_lwp.pr_flag;
    1034     pInfo->pr_uid      = pSrc->pr_uid;
    1035     pInfo->pr_gid      = pSrc->pr_gid;
    1036     pInfo->pr_pid      = pSrc->pr_pid;
    1037     pInfo->pr_ppid     = pSrc->pr_ppid;
    1038     pInfo->pr_pgrp     = pSrc->pr_pgid;
    1039     pInfo->pr_sid      = pSrc->pr_sid;
    1040     pInfo->pr_addr     = (caddr_t)pSrc->pr_addr;
    1041     pInfo->pr_size     = pSrc->pr_size;
    1042     pInfo->pr_rssize   = pSrc->pr_rssize;
    1043     pInfo->pr_wchan    = (caddr_t)pSrc->pr_lwp.pr_wchan;
    1044     pInfo->pr_start    = pSrc->pr_start;
    1045     pInfo->pr_time     = pSrc->pr_time;
    1046     pInfo->pr_pri      = pSrc->pr_lwp.pr_pri;
    1047     pInfo->pr_oldpri   = pSrc->pr_lwp.pr_oldpri;
    1048     pInfo->pr_cpu      = pSrc->pr_lwp.pr_cpu;
    1049     pInfo->pr_ottydev  = cmpdev(pSrc->pr_ttydev);
    1050     pInfo->pr_lttydev  = pSrc->pr_ttydev;
    1051     pInfo->pr_syscall  = pSrc->pr_lwp.pr_syscall;
    1052     pInfo->pr_ctime    = pSrc->pr_ctime;
    1053     pInfo->pr_bysize   = pSrc->pr_size * PAGESIZE;
    1054     pInfo->pr_byrssize = pSrc->pr_rssize * PAGESIZE;
    1055     pInfo->pr_argc     = pSrc->pr_argc;
    1056     pInfo->pr_argv     = (char **)pSrc->pr_argv;
    1057     pInfo->pr_envp     = (char **)pSrc->pr_envp;
    1058     pInfo->pr_wstat    = pSrc->pr_wstat;
    1059     pInfo->pr_pctcpu   = pSrc->pr_pctcpu;
    1060     pInfo->pr_pctmem   = pSrc->pr_pctmem;
    1061     pInfo->pr_euid     = pSrc->pr_euid;
    1062     pInfo->pr_egid     = pSrc->pr_egid;
    1063     pInfo->pr_aslwpid  = 0;
    1064     pInfo->pr_dmodel   = pSrc->pr_dmodel;
     1036
     1037    size_t offLwp         = RT_OFFSETOF(psinfo_t, pr_lwp);
     1038    size_t offLastOnProc  = RT_OFFSETOF(lwpsinfo_t, pr_last_onproc /* last member we care about in lwpsinfo_t */);
     1039    if (pSolProc->cbProcInfo >= offLwp + offLastOnProc)
     1040    {
     1041        psinfo_t *pSrc = (psinfo_t *)pSolProc->pvProcInfo;
     1042        memset(pInfo, 0, sizeof(prpsinfo_t));
     1043        pInfo->pr_state    = pSrc->pr_lwp.pr_state;
     1044        pInfo->pr_zomb     = (pInfo->pr_state == SZOMB);
     1045        RTStrCopy(pInfo->pr_clname, sizeof(pInfo->pr_clname), pSrc->pr_lwp.pr_clname);
     1046        RTStrCopy(pInfo->pr_fname, sizeof(pInfo->pr_fname), pSrc->pr_fname);
     1047        memcpy(&pInfo->pr_psargs, &pSrc->pr_psargs, sizeof(pInfo->pr_psargs));
     1048        pInfo->pr_nice     = pSrc->pr_lwp.pr_nice;
     1049        pInfo->pr_flag     = pSrc->pr_lwp.pr_flag;
     1050        pInfo->pr_uid      = pSrc->pr_uid;
     1051        pInfo->pr_gid      = pSrc->pr_gid;
     1052        pInfo->pr_pid      = pSrc->pr_pid;
     1053        pInfo->pr_ppid     = pSrc->pr_ppid;
     1054        pInfo->pr_pgrp     = pSrc->pr_pgid;
     1055        pInfo->pr_sid      = pSrc->pr_sid;
     1056        pInfo->pr_addr     = (caddr_t)pSrc->pr_addr;
     1057        pInfo->pr_size     = pSrc->pr_size;
     1058        pInfo->pr_rssize   = pSrc->pr_rssize;
     1059        pInfo->pr_wchan    = (caddr_t)pSrc->pr_lwp.pr_wchan;
     1060        pInfo->pr_start    = pSrc->pr_start;
     1061        pInfo->pr_time     = pSrc->pr_time;
     1062        pInfo->pr_pri      = pSrc->pr_lwp.pr_pri;
     1063        pInfo->pr_oldpri   = pSrc->pr_lwp.pr_oldpri;
     1064        pInfo->pr_cpu      = pSrc->pr_lwp.pr_cpu;
     1065        pInfo->pr_ottydev  = cmpdev(pSrc->pr_ttydev);
     1066        pInfo->pr_lttydev  = pSrc->pr_ttydev;
     1067        pInfo->pr_syscall  = pSrc->pr_lwp.pr_syscall;
     1068        pInfo->pr_ctime    = pSrc->pr_ctime;
     1069        pInfo->pr_bysize   = pSrc->pr_size * PAGESIZE;
     1070        pInfo->pr_byrssize = pSrc->pr_rssize * PAGESIZE;
     1071        pInfo->pr_argc     = pSrc->pr_argc;
     1072        pInfo->pr_argv     = (char **)pSrc->pr_argv;
     1073        pInfo->pr_envp     = (char **)pSrc->pr_envp;
     1074        pInfo->pr_wstat    = pSrc->pr_wstat;
     1075        pInfo->pr_pctcpu   = pSrc->pr_pctcpu;
     1076        pInfo->pr_pctmem   = pSrc->pr_pctmem;
     1077        pInfo->pr_euid     = pSrc->pr_euid;
     1078        pInfo->pr_egid     = pSrc->pr_egid;
     1079        pInfo->pr_aslwpid  = 0;
     1080        pInfo->pr_dmodel   = pSrc->pr_dmodel;
     1081
     1082        return VINF_SUCCESS;
     1083    }
     1084
     1085    CORELOGRELSYS((CORELOG_NAME "GetOldProcessInfo: Size/offset mismatch. offLwp=%u offLastOnProc=%u cbProcInfo=%u\n",
     1086                   offLwp, offLastOnProc, pSolProc->cbProcInfo));
     1087    return VERR_MISMATCH;
    10651088}
    10661089
     
    15431566            ELFWRITENOTE aElfNotes[] =
    15441567            {
    1545                 { "NT_PSINFO",     NT_PSINFO,     &pSolProc->ProcInfo,     sizeof(psinfo_t) },
     1568                { "NT_PSINFO",     NT_PSINFO,      pSolProc->pvProcInfo,   pSolProc->cbProcInfo },
    15461569                { "NT_PSTATUS",    NT_PSTATUS,    &pSolProc->ProcStatus,   sizeof(pstatus_t) },
    15471570                { "NT_AUXV",       NT_AUXV,        pSolProc->pAuxVecs,     pSolProc->cAuxVecs * sizeof(auxv_t) },
     
    19772000    if (RT_SUCCESS(rc))
    19782001    {
    1979         rc = ProcReadInfo(pSolCore);
     2002        rc = AllocMemoryArea(pSolCore);
    19802003        if (RT_SUCCESS(rc))
    19812004        {
    1982             GetOldProcessInfo(pSolCore, &pSolProc->ProcInfoOld);
    1983             if (IsProcessArchNative(pSolProc))
     2005            rc = ProcReadInfo(pSolCore);
     2006            if (RT_SUCCESS(rc))
    19842007            {
    1985                 /*
    1986                  * Read process status, information such as number of active LWPs will be
    1987                  * invalid since we just quiesced the process.
    1988                  */
    1989                 rc = ProcReadStatus(pSolCore);
     2008                rc = GetOldProcessInfo(pSolCore, &pSolProc->ProcInfoOld);
    19902009                if (RT_SUCCESS(rc))
    19912010                {
    1992                     rc = AllocMemoryArea(pSolCore);
    1993                     if (RT_SUCCESS(rc))
     2011                    if (IsProcessArchNative(pSolProc))
    19942012                    {
    1995                         struct COREACCUMULATOR
    1996                         {
    1997                             const char        *pszName;
    1998                             PFNRTSOLCOREACCUMULATOR pfnAcc;
    1999                             bool               fOptional;
    2000                         } aAccumulators[] =
    2001                         {
    2002                             { "ProcReadLdt",      &ProcReadLdt,      false },
    2003                             { "ProcReadCred",     &ProcReadCred,     false },
    2004                             { "ProcReadPriv",     &ProcReadPriv,     false },
    2005                             { "ProcReadAuxVecs",  &ProcReadAuxVecs,  false },
    2006                             { "ProcReadMappings", &ProcReadMappings, false },
    2007                             { "ProcReadThreads",  &ProcReadThreads,  false },
    2008                             { "ProcReadMiscInfo", &ProcReadMiscInfo, false }
    2009                         };
    2010 
    2011                         for (unsigned i = 0; i < RT_ELEMENTS(aAccumulators); i++)
    2012                         {
    2013                             rc = aAccumulators[i].pfnAcc(pSolCore);
    2014                             if (RT_FAILURE(rc))
    2015                             {
    2016                                 CORELOGRELSYS((CORELOG_NAME "CreateCore: %s failed. rc=%Rrc\n", aAccumulators[i].pszName, rc));
    2017                                 if (!aAccumulators[i].fOptional)
    2018                                     break;
    2019                             }
    2020                         }
    2021 
     2013                        /*
     2014                         * Read process status, information such as number of active LWPs will be
     2015                         * invalid since we just quiesced the process.
     2016                         */
     2017                        rc = ProcReadStatus(pSolCore);
    20222018                        if (RT_SUCCESS(rc))
    20232019                        {
    2024                             pSolCore->fIsValid = true;
    2025                             return VINF_SUCCESS;
     2020                            struct COREACCUMULATOR
     2021                            {
     2022                                const char        *pszName;
     2023                                PFNRTSOLCOREACCUMULATOR pfnAcc;
     2024                                bool               fOptional;
     2025                            } aAccumulators[] =
     2026                            {
     2027                                { "ProcReadLdt",      &ProcReadLdt,      false },
     2028                                { "ProcReadCred",     &ProcReadCred,     false },
     2029                                { "ProcReadPriv",     &ProcReadPriv,     false },
     2030                                { "ProcReadAuxVecs",  &ProcReadAuxVecs,  false },
     2031                                { "ProcReadMappings", &ProcReadMappings, false },
     2032                                { "ProcReadThreads",  &ProcReadThreads,  false },
     2033                                { "ProcReadMiscInfo", &ProcReadMiscInfo, false }
     2034                            };
     2035
     2036                            for (unsigned i = 0; i < RT_ELEMENTS(aAccumulators); i++)
     2037                            {
     2038                                rc = aAccumulators[i].pfnAcc(pSolCore);
     2039                                if (RT_FAILURE(rc))
     2040                                {
     2041                                    CORELOGRELSYS((CORELOG_NAME "CreateCore: %s failed. rc=%Rrc\n", aAccumulators[i].pszName, rc));
     2042                                    if (!aAccumulators[i].fOptional)
     2043                                        break;
     2044                                }
     2045                            }
     2046
     2047                            if (RT_SUCCESS(rc))
     2048                            {
     2049                                pSolCore->fIsValid = true;
     2050                                return VINF_SUCCESS;
     2051                            }
     2052
     2053                            FreeMemoryArea(pSolCore);
    20262054                        }
    2027 
    2028                         FreeMemoryArea(pSolCore);
     2055                        else
     2056                            CORELOGRELSYS((CORELOG_NAME "CreateCore: ProcReadStatus failed. rc=%Rrc\n", rc));
    20292057                    }
    20302058                    else
    2031                         CORELOGRELSYS((CORELOG_NAME "CreateCore: AllocMemoryArea failed. rc=%Rrc\n", rc));
     2059                    {
     2060                        CORELOGRELSYS((CORELOG_NAME "CreateCore: IsProcessArchNative failed.\n"));
     2061                        rc = VERR_BAD_EXE_FORMAT;
     2062                    }
    20322063                }
    20332064                else
    2034                     CORELOGRELSYS((CORELOG_NAME "CreateCore: ProcReadStatus failed. rc=%Rrc\n", rc));
     2065                    CORELOGRELSYS((CORELOG_NAME "CreateCore: GetOldProcessInfo failed. rc=%Rrc\n", rc));
    20352066            }
    20362067            else
    2037             {
    2038                 CORELOGRELSYS((CORELOG_NAME "CreateCore: IsProcessArchNative failed.\n"));
    2039                 rc = VERR_BAD_EXE_FORMAT;
    2040             }
     2068                CORELOGRELSYS((CORELOG_NAME "CreateCore: ProcReadInfo failed. rc=%Rrc\n", rc));
    20412069        }
    20422070        else
    2043             CORELOGRELSYS((CORELOG_NAME "CreateCore: ProcReadInfo failed. rc=%Rrc\n", rc));
     2071            CORELOGRELSYS((CORELOG_NAME "CreateCore: AllocMemoryArea failed. rc=%Rrc\n", rc));
    20442072
    20452073        /*
  • trunk/src/VBox/Runtime/r3/solaris/coredumper-solaris.h

    r56290 r62096  
    103103    char                           *pszExecName;                /**< Name of the executable file */
    104104#ifdef RT_OS_SOLARIS
    105     psinfo_t                        ProcInfo;                   /**< Process info. */
     105    void                           *pvProcInfo;                 /**< Process info. */
     106    size_t                          cbProcInfo;                 /**< Size of the process info. */
    106107    prpsinfo_t                      ProcInfoOld;                /**< Process info. Older version (for GDB compat.) */
    107108    pstatus_t                       ProcStatus;                 /**< Process status info. */
Note: See TracChangeset for help on using the changeset viewer.

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