void sptrace_clear(PsmPartition trace) { PsmAddress traceHeaderAddress; TraceHeader *trh; PsmAddress elt; PsmAddress nextElt; PsmAddress itemAddress; TraceItem *item; if (!trace) return; traceHeaderAddress = psm_get_root(trace); trh = (TraceHeader *) psp(trace, traceHeaderAddress); CHKVOID(trh); for (elt = sm_list_first(trace, trh->log); elt; elt = nextElt) { nextElt = sm_list_next(trace, elt); itemAddress = sm_list_data(trace, elt); item = (TraceItem *) psp(trace, itemAddress); CHKVOID(item); if (item->opType == OP_ALLOCATE || item->opType == OP_FREE) { if (item->refOpNbr == 0) { continue; /* Not matched. */ } /* Delete matched activity from log. */ psm_free(trace, itemAddress); CHKVOID(sm_list_delete(trace, elt, NULL, NULL) == 0); } } }
PsmPartition sptrace_join(int smkey, int smsize, char *sm, PsmPartition trace, char *name) { int nameLen; int smid; PsmMgtOutcome outcome; TraceHeader *trh; CHKNULL(trace); CHKNULL(smsize > 0); CHKNULL(name); if ((nameLen = strlen(name)) < 1 || nameLen > 31) { sptracePrint("start: name must be 1-31 characters."); return NULL; } /* Attach to shared memory used for trace operations. */ if (sm_ShmAttach(smkey, smsize, (char **) &sm, &smid) < 0) { sptracePrint("join: can't attach shared memory for trace."); return NULL; } /* Examine the shared memory region. */ if (psm_manage(sm, smsize, name, &trace, &outcome) < 0) { sptracePrint("join: shared memory mgt failed."); return NULL; } switch (outcome) { case Refused: sptracePrint("join: can't psm_manage shared memory."); return NULL; case Redundant: trh = (TraceHeader *) psp(trace, psm_get_root(trace)); if (trh == NULL || strcmp(name, trh->name) != 0) { sptracePrint("join: shared memory used otherwise."); return NULL; } return trace; /* Have joined the trace. */ default: break; } sptracePrint("join: trace episode not yet started."); return NULL; }
void sptrace_stop(PsmPartition trace) { char *sm; TraceHeader *trh; int smId = 0; if (!trace) return; trh = (TraceHeader *) psp(trace, psm_get_root(trace)); if (trh) { smId = trh->traceSmId; } sm = psm_space(trace); psm_erase(trace); sm_ShmDetach(sm); if (smId) { sm_ShmDestroy(smId); } }
PsmPartition sptrace_start(int smkey, int smsize, char *sm, PsmPartition trace, char *name) { int nameLen; int smid; PsmMgtOutcome outcome; TraceHeader *trh; PsmAddress traceHeaderAddress; CHKNULL(trace); CHKNULL(smsize > 0); CHKNULL(name); if ((nameLen = strlen(name)) < 1 || nameLen > 31) { sptracePrint("start: name must be 1-31 characters."); return NULL; } /* Attach to shared memory used for trace operations. */ if (sm_ShmAttach(smkey, smsize, &sm, &smid) < 0) { sptracePrint("start: can't attach shared memory for trace."); return NULL; } /* Manage the shared memory region. "Trace" argument * is normally NULL. */ if (psm_manage(sm, smsize, name, &trace, &outcome) < 0) { sptracePrint("start: shared memory mgt failed."); return NULL; } switch (outcome) { case Refused: sptracePrint("start: can't psm_manage shared memory."); return NULL; case Redundant: trh = (TraceHeader *) psp(trace, psm_get_root(trace)); if (trh == NULL || strcmp(name, trh->name) != 0) { sptracePrint("start: shared memory used otherwise."); return NULL; } return trace; /* Trace already started. */ default: break; } /* Initialize the shared memory region for tracing. */ traceHeaderAddress = psm_zalloc(trace, sizeof(TraceHeader)); if (traceHeaderAddress == 0) { sptracePrint("start: not enough memory for header."); sm_ShmDetach(sm); sm_ShmDestroy(smid); return NULL; } oK(psm_set_root(trace, traceHeaderAddress)); trh = (TraceHeader *) psp(trace, traceHeaderAddress); CHKNULL(trh); trh->traceSmId = smid; memset(trh->name, 0, sizeof trh->name); istrcpy(trh->name, name, sizeof trh->name); trh->opCount = 0; trh->files = sm_list_create(trace); if (trh->files == 0) { sptracePrint("start: not enough memory for files list."); sm_ShmDetach(sm); sm_ShmDestroy(smid); return NULL; } trh->log = sm_list_create(trace); if (trh->log == 0) { sptracePrint("start: not enough memory for log."); sm_ShmDetach(sm); sm_ShmDestroy(smid); return NULL; } return trace; }
void sptrace_report(PsmPartition trace, int verbose) { PsmAddress traceHeaderAddress; TraceHeader *trh; PsmAddress elt; TraceItem *item; char *fileName; char buffer[384]; int len; char buf2[256]; if (!trace) return; traceHeaderAddress = psm_get_root(trace); trh = (TraceHeader *) psp(trace, traceHeaderAddress); CHKVOID(trh); for (elt = sm_list_first(trace, trh->log); elt; elt = sm_list_next(trace, elt)) { item = (TraceItem *) psp(trace, sm_list_data(trace, elt)); CHKVOID(item); fileName = (char *) psp(trace, item->fileName); isprintf(buffer, sizeof buffer, "(%5d) at line %6d of %32.32s \ (pid %5d): ", item->opNbr, item->lineNbr, fileName, item->taskId); len = strlen(buffer); switch (item->opType) { case OP_ALLOCATE: isprintf(buf2, sizeof buf2, "allocated object %6ld of \ size %6d, ", item->objectAddress, item->objectSize); istrcpy(buffer + len, buf2, sizeof buffer - len); if (item->refOpNbr == 0) { len = strlen(buffer); istrcpy(buffer + len, "never freed", sizeof buffer - len); } else { if (!verbose) { continue; } len = strlen(buffer); fileName = (char *) psp(trace, item->refFileName); isprintf(buf2, sizeof buf2, "freed in (%5d) \ at line %6d of %32.32s (pid %5d)", item->refOpNbr, item->refLineNbr, fileName, item->refTaskId); istrcpy(buffer + len, buf2, sizeof buffer - len); } break; case OP_MEMO: isprintf(buf2, sizeof buf2, "re %6ld, '%.128s'", item->objectAddress, (char *) psp(trace, item->msg)); istrcpy(buffer + len, buf2, sizeof buffer - len); break; case OP_FREE: isprintf(buf2, sizeof buf2, "freed object %6ld, ", item->objectAddress); istrcpy(buffer + len, buf2, sizeof buffer - len); if (item->refOpNbr == 0) { len = strlen(buffer); istrcpy(buffer + len, "not currently allocated", sizeof buffer - len); } else { if (!verbose) { continue; } len = strlen(buffer); fileName = (char *) psp(trace, item->refFileName); CHKVOID(fileName); isprintf(buf2, sizeof buf2, "allocated in \ (%5d) at line %6d of %32.32s (pid %5d)", item->refOpNbr, item->refLineNbr, fileName, item->refTaskId); istrcpy(buffer + len, buf2, sizeof buffer - len); } break; } writeMemo(buffer); } }
static void logEvent(PsmPartition trace, int opType, unsigned long addr, int objectSize, char *msg, char *fileName, int lineNbr, PsmAddress *eltp) { PsmAddress traceHeaderAddress; TraceHeader *trh; PsmAddress itemAddr; TraceItem *item; int buflen; PsmAddress elt; if (eltp) { *eltp = 0; } traceHeaderAddress = psm_get_root(trace); trh = (TraceHeader *) psp(trace, traceHeaderAddress); if (trh == NULL) return; itemAddr = psm_zalloc(trace, sizeof(TraceItem)); if (itemAddr == 0) { discardEvent(trace); return; } item = (TraceItem *) psp(trace, itemAddr); memset((char *) item, 0, sizeof(TraceItem)); if (msg) { buflen = strlen(msg) + 1; item->msg = psm_zalloc(trace, buflen); if (item->msg == 0) { discardEvent(trace); return; } istrcpy((char *) psp(trace, item->msg), msg, buflen); } item->taskId = sm_TaskIdSelf(); item->fileName = findFileName(trace, trh, fileName); if (item->fileName == 0) { return; /* Events are being discarded. */ } item->lineNbr = lineNbr; trh->opCount++; item->opNbr = trh->opCount; item->opType = opType; item->objectAddress = addr; item->objectSize = objectSize; elt = sm_list_insert_last(trace, trh->log, itemAddr); if (elt == 0) { discardEvent(trace); return; } if (eltp) { *eltp = elt; } }
int main(int argc, char **argv) #endif { char *wmspace; int wmid; PsmPartition wm = NULL; PsmMgtOutcome outcome; PsmAddress testlist; sm_SemId semaphore; int cycleNbr = 1; char fileName[256]; int outputFile; PsmAddress lineListElt; PsmAddress lineAddress; char *line; if (sm_ipc_init() < 0) { return 0; } if (sm_ShmAttach(0x1108, 10000000, &wmspace, &wmid) < 0) { PERROR("can't attach to shared memory"); return 0; } if (psm_manage(wmspace, 10000000, "file2sm", &wm, &outcome) < 0 || outcome == Refused) { PUTS("can't manage shared memory"); return 0; } testlist = psm_get_root(wm); if (testlist == 0) { testlist = sm_list_create(wm); if (testlist == 0) { PUTS("can't create shared memory list"); return 0; } psm_set_root(wm, testlist); } semaphore = sm_SemCreate(0x1101, SM_SEM_FIFO); if (semaphore < 0) { PUTS("can't create semaphore"); return 0; } PUTMEMO("Working on cycle", utoa(cycleNbr)); isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = iopen(fileName, O_WRONLY | O_APPEND, 0666); if (outputFile < 0) { PERROR("can't open output file"); return 0; } while (1) { while (sm_list_length(wm, testlist) == 0) { sm_SemTake(semaphore); /* Wait for line. */ } lineListElt = sm_list_first(wm, testlist); lineAddress = sm_list_data(wm, lineListElt); line = psp(wm, lineAddress); /* Process text of line. */ if (strcmp(line, "*** End of the file ***\n") == 0) { /* Close file, open next one. */ close(outputFile); cycleNbr++; PUTMEMO("Working on cycle", utoa(cycleNbr)); isprintf(fileName, sizeof fileName, "file_copy_%d", cycleNbr); outputFile = iopen(fileName, O_WRONLY | O_APPEND, 0666); if (outputFile < 0) { PERROR("Can't open output file"); return 0; } } else /* Just write line to output file. */ { if (iputs(outputFile, line) < 0) { close(outputFile); PERROR("Can't write to output file"); return 0; } } /* Delete line from shared memory list. */ psm_free(wm, lineAddress); CHKZERO(sm_list_delete(wm, lineListElt, (SmListDeleteFn) NULL, NULL) == 0); } }