From 2c6f9105ba022a491b4c6a298b9f0ddbc92ecca3 Mon Sep 17 00:00:00 2001 From: "blythe%netscape.com" Date: Fri, 3 May 2002 00:32:23 +0000 Subject: [PATCH] Turn options into arrays instead of heap to allow easy copying into a per thread/client option duplicate. --- tools/trace-malloc/spacetrace.c | 160 ++++++++++++-------------------- tools/trace-malloc/spacetrace.h | 40 ++++---- 2 files changed, 74 insertions(+), 126 deletions(-) diff --git a/tools/trace-malloc/spacetrace.c b/tools/trace-malloc/spacetrace.c index 16b83f29965..64042bfe7db 100644 --- a/tools/trace-malloc/spacetrace.c +++ b/tools/trace-malloc/spacetrace.c @@ -312,17 +312,17 @@ int initOptions(int aArgCount, char** aArgArray) /* ** Set the program name. */ - globals.mOptions.mProgramName = aArgArray[0]; + PR_snprintf(globals.mOptions.mProgramName, sizeof(globals.mOptions.mProgramName), "%s", aArgArray[0]); /* ** As a default, stdin is the input. */ - globals.mOptions.mFileName = stdinDash; + PR_snprintf(globals.mOptions.mFileName, sizeof(globals.mOptions.mFileName), "%s", stdinDash); /* ** As a default, this directory is the output. */ - globals.mOptions.mOutputDir = outputDir; + PR_snprintf(globals.mOptions.mOutputDir, sizeof(globals.mOptions.mOutputDir), "%s", outputDir); /* ** As a default, this is the port to listen for http requests. @@ -377,13 +377,13 @@ int initOptions(int aArgCount, char** aArgArray) /* ** category file - **/ - globals.mOptions.mCategoryFile = "rules.txt"; + */ + PR_snprintf(globals.mOptions.mCategoryFile, sizeof(globals.mOptions.mCategoryFile), "%s", "rules.txt"); /* ** Default category name - name of root category */ - globals.mOptions.mCategoryName = strdup(ST_ROOT_CATEGORY_NAME); + PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", ST_ROOT_CATEGORY_NAME); /* ** Go through all arguments. @@ -409,7 +409,7 @@ int initOptions(int aArgCount, char** aArgArray) ** If the entire option is a dash, ** then input is stdin. */ - globals.mOptions.mFileName = stdinDash; + PR_snprintf(globals.mOptions.mFileName, sizeof(globals.mOptions.mFileName), "%s", stdinDash); } break; @@ -478,7 +478,7 @@ int initOptions(int aArgCount, char** aArgArray) */ if('\0' != aArgArray[traverse][2]) { - globals.mOptions.mOutputDir = &aArgArray[traverse][2]; + PR_snprintf(globals.mOptions.mOutputDir, sizeof(globals.mOptions.mOutputDir), "%s", &aArgArray[traverse][2]); } else { @@ -830,16 +830,12 @@ int initOptions(int aArgCount, char** aArgArray) */ for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++) { - if(NULL != globals.mOptions.mRestrictText[looper]) + if('\0' != globals.mOptions.mRestrictText[looper][0]) { continue; } - globals.mOptions.mRestrictText[looper] = strdup(&aArgArray[traverse][2]); - if(NULL == globals.mOptions.mRestrictText[looper]) - { - retval = __LINE__; - } + PR_snprintf(globals.mOptions.mRestrictText[looper], sizeof(globals.mOptions.mRestrictText[looper]), "%s", &aArgArray[traverse][2]); break; } @@ -866,9 +862,7 @@ int initOptions(int aArgCount, char** aArgArray) */ if('\0' != aArgArray[traverse][2]) { - if (globals.mOptions.mCategoryFile) - free(globals.mOptions.mCategoryFile); - globals.mOptions.mCategoryFile = strdup(&aArgArray[traverse][2]); + PR_snprintf(globals.mOptions.mCategoryFile, sizeof(globals.mOptions.mCategoryFile), "%s", &aArgArray[traverse][2]); } else { @@ -885,9 +879,7 @@ int initOptions(int aArgCount, char** aArgArray) */ if('\0' != aArgArray[traverse][2]) { - if (globals.mOptions.mCategoryName) - free(globals.mOptions.mCategoryName); - globals.mOptions.mCategoryName = strdup(&aArgArray[traverse][2]); + PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", &aArgArray[traverse][2]); } else { @@ -923,7 +915,7 @@ int initOptions(int aArgCount, char** aArgArray) /* ** File to process. */ - globals.mOptions.mFileName = aArgArray[traverse]; + PR_snprintf(globals.mOptions.mFileName, sizeof(globals.mOptions.mFileName), "%s", aArgArray[traverse]); } } @@ -1633,7 +1625,7 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions) */ for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++) { - if(NULL != globals.mOptions.mRestrictText[looper] && '\0' != globals.mOptions.mRestrictText[looper][0]) + if('\0' != globals.mOptions.mRestrictText[looper][0]) { if(0 == hasCallsiteMatch(current->mEvents[0].mCallsite, globals.mOptions.mRestrictText[looper], ST_FOLLOW_PARENTS)) { @@ -1929,6 +1921,7 @@ STRun* createRunFromGlobal(void) if(NULL != retval) { + STCategoryNode* node = NULL; int failure = 0; int harvestRes = harvestRun(&globals.mRun, retval, NULL); if(0 == harvestRes) @@ -1966,18 +1959,14 @@ STRun* createRunFromGlobal(void) ** if we are focussing on a category, return that run instead of ** the harvested run. Make sure to recalculate cost. */ - if (globals.mOptions.mCategoryName) + node = findCategoryNode(globals.mOptions.mCategoryName, &globals); + if (node) { - STCategoryNode* node = findCategoryNode(globals.mOptions.mCategoryName, &globals); - if (node) - { - /* Recalculate cost of run */ - recalculateRunCost(node->run); - - retval = node->run; - } + /* Recalculate cost of run */ + recalculateRunCost(node->run); + + retval = node->run; } - } return retval; @@ -2704,9 +2693,9 @@ void htmlAnchor(STRequest* inRequest, const char* aHref, const char* aText, cons /* ** In any mode, don't make an href to the current page. */ - if(0 != anchorLive && NULL != inRequest->mFileName) + if(0 != anchorLive && NULL != inRequest->mGetFileName) { - if(0 == strcmp(aHref, inRequest->mFileName)) + if(0 == strcmp(aHref, inRequest->mGetFileName)) { anchorLive = 0; } @@ -3188,11 +3177,11 @@ int getDataPRUint64(const char* aGetData, const char* aCheckFor, PRUint64* aStor ** Pull out the string data, if specified. ** Return !0 on failure. */ -int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResult, int* aChanged) +int getDataString(const char* aGetData, const char* aCheckFor, char* aStoreResult, int inStoreResultLength, int* aChanged) { int retval = 0; - if(NULL != aGetData && NULL != aCheckFor && NULL != aStoreResult) + if(NULL != aGetData && NULL != aCheckFor && NULL != aStoreResult && 0 != inStoreResultLength) { const char* found = NULL; PRInt32 scanRes = 0; @@ -3206,7 +3195,7 @@ int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResu int length = 0; const char* dataPoint = NULL; const char* endPoint = NULL; - char* oldResult = NULL; + char oldResult[ST_OPTION_STRING_MAX]; int theLen = 0; /* @@ -3228,56 +3217,52 @@ int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResu /* ** Store original value if present. */ - if(NULL != *aStoreResult) - { - oldResult = *aStoreResult; - } + PR_snprintf(oldResult, sizeof(oldResult), "%s", aStoreResult); /* - ** Allocate space for new string. + ** We have enough space for this? */ theLen = (int)(endPoint - dataPoint); - *aStoreResult = (char*)malloc((size_t)(theLen + 1)); - if(NULL != *aStoreResult) + if(inStoreResultLength > theLen) { int index1 = 0; int index2 = 0; - strncpy(*aStoreResult, dataPoint, theLen); - (*aStoreResult)[theLen] = '\0'; + strncpy(aStoreResult, dataPoint, theLen); + aStoreResult[theLen] = '\0'; /* ** Here's a totally suboptimal and bug prone unhexcaper. */ for(; index1 <= theLen; index1++) { - if('%' == (*aStoreResult)[index1] && '\0' != (*aStoreResult)[index1 + 1] && '\0' != (*aStoreResult)[index1 + 2]) + if('%' == aStoreResult[index1] && '\0' != aStoreResult[index1 + 1] && '\0' != aStoreResult[index1 + 2]) { int unhex = 0; - if('9' >= (*aStoreResult)[index1 + 1]) + if('9' >= aStoreResult[index1 + 1]) { - unhex |= (((*aStoreResult)[index1 + 1] - '0') << 4); + unhex |= ((aStoreResult[index1 + 1] - '0') << 4); } else { - unhex |= ((toupper((*aStoreResult)[index1 + 1]) - 'A' + 10) << 4); + unhex |= ((toupper(aStoreResult[index1 + 1]) - 'A' + 10) << 4); } - if('9' >= (*aStoreResult)[index1 + 2]) + if('9' >= aStoreResult[index1 + 2]) { - unhex |= ((*aStoreResult)[index1 + 2] - '0'); + unhex |= (aStoreResult[index1 + 2] - '0'); } else { - unhex |= (toupper((*aStoreResult)[index1 + 2]) - 'A' + 10); + unhex |= (toupper(aStoreResult[index1 + 2]) - 'A' + 10); } index1 += 2; - (*aStoreResult)[index1] = unhex; + aStoreResult[index1] = unhex; } - (*aStoreResult)[index2++] = (*aStoreResult)[index1]; + aStoreResult[index2++] = aStoreResult[index1]; } /* @@ -3287,25 +3272,16 @@ int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResu { if(NULL != oldResult) { - if(0 != strcmp(oldResult, *aStoreResult)) + if(0 != strcmp(oldResult, aStoreResult)) { (*aChanged) = (*aChanged) + 1; } } - else if('\0' != (*aStoreResult)[0]) + else if('\0' != aStoreResult[0]) { (*aChanged) = (*aChanged) + 1; } } - - /* - ** Free off the prior value if relevant. - */ - if(NULL != oldResult) - { - free(oldResult); - oldResult = NULL; - } } else { @@ -5117,19 +5093,17 @@ int applySettings(STRequest* inRequest) for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++) { PR_snprintf(looper_buf, sizeof(looper_buf), "mRestrictText%d", looper); - getRes += getDataString(inRequest->mGetData, looper_buf, &globals.mOptions.mRestrictText[looper], &changedSet); + getRes += getDataString(inRequest->mGetData, looper_buf, globals.mOptions.mRestrictText[looper], sizeof(globals.mOptions.mRestrictText[looper]), &changedSet); } - getRes += getDataString(inRequest->mGetData, "mCategoryName", &globals.mOptions.mCategoryName, &changedCategory); + getRes += getDataString(inRequest->mGetData, "mCategoryName", globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), &changedCategory); /* ** Sanity check options */ - if (changedCategory && (!globals.mOptions.mCategoryName || !*globals.mOptions.mCategoryName + if (changedCategory && (!globals.mOptions.mCategoryName[0] || !findCategoryNode(globals.mOptions.mCategoryName, &globals))) { - if (globals.mOptions.mCategoryName) - free(globals.mOptions.mCategoryName); - globals.mOptions.mCategoryName = strdup(ST_ROOT_CATEGORY_NAME); + PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", ST_ROOT_CATEGORY_NAME); } /* @@ -5155,18 +5129,14 @@ int applySettings(STRequest* inRequest) ** right node and set the cache.mSortedRun. We need to recompute ** cost though. But that is cheap. */ - if (globals.mOptions.mCategoryName) + STCategoryNode* node = findCategoryNode(globals.mOptions.mCategoryName, &globals); + if (node) { - STCategoryNode* node = findCategoryNode(globals.mOptions.mCategoryName, &globals); - if (node) - { - /* Recalculate cost of run */ - recalculateRunCost(node->run); - - globals.mCache.mSortedRun = node->run; - } + /* Recalculate cost of run */ + recalculateRunCost(node->run); + + globals.mCache.mSortedRun = node->run; } - } @@ -5324,7 +5294,7 @@ int displaySettings(STRequest* inRequest) PR_fprintf(inRequest->mFD, "Keep all the strings together near the top of this list, as the code will stop trying to match on the first empty string.
\n"); for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++) { - PR_fprintf(inRequest->mFD, "
\n", looper, NULL == globals.mOptions.mRestrictText[looper] ? "" : globals.mOptions.mRestrictText[looper]); + PR_fprintf(inRequest->mFD, "
\n", looper, globals.mOptions.mRestrictText[looper]); } PR_fprintf(inRequest->mFD, "
\n"); @@ -5423,7 +5393,7 @@ int handleRequest(tmreader* aTMR, PRFileDesc* aFD, const char* aFileName, const memset(&request, 0, sizeof(request)); request.mFD = aFD; - request.mFileName = aFileName; + request.mGetFileName = aFileName; request.mGetData = aGetData; /* @@ -5484,10 +5454,10 @@ int handleRequest(tmreader* aTMR, PRFileDesc* aFD, const char* aFileName, const if(request.mGetData && *request.mGetData) { - char* categoryName = NULL; - int getRes = getDataString(request.mGetData, "mCategory", &categoryName, NULL); + char categoryName[ST_OPTION_STRING_MAX]; + int getRes = getDataString(request.mGetData, "mCategory", categoryName, sizeof(categoryName), NULL); STCategoryNode* node; - if (categoryName && *categoryName && + if (*categoryName && strcmp(categoryName, globals.mOptions.mCategoryName) && (node = findCategoryNode(categoryName, &globals))) { @@ -5497,9 +5467,7 @@ int handleRequest(tmreader* aTMR, PRFileDesc* aFD, const char* aFileName, const recalculateRunCost(node->run); globals.mCache.mSortedRun = node->run; - if (globals.mOptions.mCategoryName) - free(globals.mOptions.mCategoryName); - globals.mOptions.mCategoryName = categoryName; + PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", categoryName); } } @@ -6334,18 +6302,6 @@ int main(int aArgCount, char** aArgArray) } } - /* - ** Options cleanup. - */ - for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++) - { - if(NULL != globals.mOptions.mRestrictText[looper]) - { - free(globals.mOptions.mRestrictText[looper]); - globals.mOptions.mRestrictText[looper] = NULL; - } - } - if(0 != retval) { REPORT_ERROR(retval, main); diff --git a/tools/trace-malloc/spacetrace.h b/tools/trace-malloc/spacetrace.h index 41f71cbf730..f0748a742ed 100644 --- a/tools/trace-malloc/spacetrace.h +++ b/tools/trace-malloc/spacetrace.h @@ -136,6 +136,11 @@ */ #define ST_ROOT_CATEGORY_NAME "All" +/* +** Size of our option string buffers. +*/ +#define ST_OPTION_STRING_MAX 256 + /* ** Set the desired resolution of the timevals. ** The resolution is just mimicking what is recorded in the trace-malloc @@ -392,18 +397,18 @@ typedef struct __struct_STOptions /* ** The string which identifies this program. */ - const char* mProgramName; + char mProgramName[ST_OPTION_STRING_MAX]; /* ** File from which we retrieve the input. ** The input should have been generated from a trace malloc run. */ - const char* mFileName; + char mFileName[ST_OPTION_STRING_MAX]; /* ** Which directory we will take over and write our output. */ - const char* mOutputDir; + char mOutputDir[ST_OPTION_STRING_MAX]; /* ** The various batch mode requests we've received. @@ -480,33 +485,20 @@ typedef struct __struct_STOptions /* ** Restrict callsite backtraces to those containing text. */ - char* mRestrictText[ST_SUBSTRING_MATCH_MAX]; + char mRestrictText[ST_SUBSTRING_MATCH_MAX][ST_OPTION_STRING_MAX]; /* ** File containing rules to categorize allocations */ - char* mCategoryFile; + char mCategoryFile[ST_OPTION_STRING_MAX]; - /*n - ** Category to focus report on. NULL if not focussing on a category. + /* + ** Category to focus report on. '\0' if not focussing on a category. */ - char *mCategoryName; + char mCategoryName[ST_OPTION_STRING_MAX]; } STOptions; -/* -** STRequestOptions -** -** These options are likely to change on a per request/client basis. -** Careful on adding too many options here, this struct also hashes -** our content cache and more options means fewer cache hits. -*/ -typedef struct __struct_STRequestOptions -{ - int nothing; -} -STRequestOptions; - /* ** STRequest ** @@ -522,7 +514,7 @@ typedef struct __struct_STRequest /* ** The filename requested. */ - const char* mFileName; + const char* mGetFileName; /* ** The GET form data, if any. @@ -532,7 +524,7 @@ typedef struct __struct_STRequest /* ** Options specific to this request. */ - STRequestOptions mOptions; + STOptions mOptions; } STRequest; /* @@ -552,7 +544,7 @@ typedef struct __struct_STCache /* ** Category the mSortedRun belongs to. NULL if not to any category. */ - const char *mCategoryName; + char mCategoryName[ST_OPTION_STRING_MAX]; /* ** Footprint graph cache.