LCOV - app.info - nsprpub/pr/src/misc/prtrace.c

LCOV - code coverage report
| Current view: | directory - nsprpub/pr/src/misc - prtrace.c (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 319 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 16 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is the Netscape Portable Runtime (NSPR).
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1998-2000
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : /*
          39                 : ** prtrace.c -- NSPR Trace Instrumentation
          40                 : **
          41                 : ** Implement the API defined in prtrace.h
          42                 : **
          43                 : **
          44                 : **
          45                 : */
          46                 :
          47                 : #include <string.h>
          48                 : #include "primpl.h"
          49                 :
          50                 :
          51                 : #define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 )
          52                 : #define DEFAULT_BUFFER_SEGMENTS    2
          53                 :
          54                 : /*
          55                 : ** Enumerate states in a RName structure
          56                 : */
          57                 : typedef enum TraceState
          58                 : {
          59                 :     Running = 1,
          60                 :     Suspended = 2
          61                 : } TraceState;
          62                 :
          63                 : /*
          64                 : ** Define QName structure
          65                 : */
          66                 : typedef struct QName
          67                 : {
          68                 :     PRCList link;
          69                 :     PRCList rNameList;
          70                 :     char    name[PRTRACE_NAME_MAX+1];
          71                 : } QName;
          72                 :
          73                 : /*
          74                 : ** Define RName structure
          75                 : */
          76                 : typedef struct RName
          77                 : {
          78                 :     PRCList link;
          79                 :     PRLock  *lock;
          80                 :     QName   *qName;
          81                 :     TraceState state;
          82                 :     char    name[PRTRACE_NAME_MAX+1];
          83                 :     char    desc[PRTRACE_DESC_MAX+1];
          84                 : } RName;
          85                 :
          86                 :
          87                 : /*
          88                 : ** The Trace Facility database
          89                 : **
          90                 : */
          91                 : static PRLogModuleInfo *lm;
          92                 :
          93                 : static PRLock      *traceLock;      /* Facility Lock */
          94                 : static PRCList     qNameList;       /* anchor to all QName structures */
          95                 : static TraceState traceState = Running;
          96                 :
          97                 : /*
          98                 : ** in-memory trace buffer controls
          99                 : */
         100                 : static  PRTraceEntry    *tBuf;      /* pointer to buffer */
         101                 : static  PRInt32         bufSize;    /* size of buffer, in bytes, rounded up to sizeof(PRTraceEntry) */
         102                 : static  volatile PRInt32  next;     /* index to next PRTraceEntry */
         103                 : static  PRInt32         last;       /* index of highest numbered trace entry */
         104                 :
         105                 : /*
         106                 : ** Real-time buffer capture controls
         107                 : */
         108                 : static PRInt32 fetchLastSeen = 0;
         109                 : static PRBool  fetchLostData = PR_FALSE;
         110                 :
         111                 : /*
         112                 : ** Buffer write-to-file controls
         113                 : */
         114                 : static  PRLock      *logLock;               /* Sync lock */
         115                 : static  PRCondVar   *logCVar;               /* Sync Condidtion Variable */
         116                 : /*
         117                 : ** Inter-thread state communication.
         118                 : ** Controling thread writes to logOrder under protection of logCVar
         119                 : ** the logging thread reads logOrder and sets logState on Notify.
         120                 : **
         121                 : ** logSegments, logCount, logLostData must be read and written under
         122                 : ** protection of logLock, logCVar.
         123                 : **
         124                 : */
         125                 : static  enum LogState
         126                 : {
         127                 :     LogNotRunning,  /* Initial state */
         128                 :     LogReset,       /* Causes logger to re-calc controls */
         129                 :     LogActive,      /* Logging in progress, set only by log thread */
         130                 :     LogSuspend,     /* Suspend Logging */
         131                 :     LogResume,      /* Resume Logging => LogActive */
         132                 :     LogStop         /* Stop the log thread */
         133                 : }   logOrder, logState, localState;         /* controlling state variables */
         134                 : static  PRInt32     logSegments;            /* Number of buffer segments */
         135                 : static  PRInt32     logEntries;             /* number of Trace Entries in the buffer */
         136                 : static  PRInt32     logEntriesPerSegment;   /* number of PRTraceEntries per buffer segment */
         137                 : static  PRInt32     logSegSize;             /* size of buffer segment */
         138                 : static  PRInt32     logCount;               /* number of segments pending output */
         139                 : static  PRInt32     logLostData;            /* number of lost log buffer segments */
         140                 :
         141                 : /*
         142                 : ** end Trace Database
         143                 : **
         144                 : */
         145                 :
         146                 : /*
         147                 : ** _PR_InitializeTrace() -- Initialize the trace facility
         148                 : */
         149               0 : static void NewTraceBuffer( PRInt32 size )
         150                 : {
         151                 :     /*
         152                 :     ** calculate the size of the buffer
         153                 :     ** round down so that each segment has the same number of
         154                 :     ** trace entries
         155                 :     */
         156               0 :     logSegments = DEFAULT_BUFFER_SEGMENTS;
         157               0 :     logEntries = size / sizeof(PRTraceEntry);
         158               0 :     logEntriesPerSegment = logEntries / logSegments;
         159               0 :     logEntries = logSegments * logEntriesPerSegment;
         160               0 :     bufSize = logEntries * sizeof(PRTraceEntry);
         161               0 :     logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry);
         162               0 :     PR_ASSERT( bufSize != 0);
         163               0 :     PR_LOG( lm, PR_LOG_ERROR,
         164                 :         ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld",
         165                 :             logSegments, logEntries, logEntriesPerSegment, logSegSize ));
         166                 :
         167                 :
         168               0 :     tBuf = PR_Malloc( bufSize );
         169               0 :     if ( tBuf == NULL )
         170                 :     {
         171               0 :         PR_LOG( lm, PR_LOG_ERROR,
         172                 :             ("PRTrace: Failed to get trace buffer"));
         173               0 :         PR_ASSERT( 0 );
         174                 :     }
         175                 :     else
         176                 :     {
         177               0 :         PR_LOG( lm, PR_LOG_NOTICE,
         178                 :             ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf));
         179                 :     }
         180                 :
         181               0 :     next = 0;
         182               0 :     last = logEntries -1;
         183               0 :     logCount = 0;
         184               0 :     logLostData = PR_TRUE; /* not really on first call */
         185               0 :     logOrder = LogReset;
         186                 :
         187               0 : } /* end NewTraceBuffer() */
         188                 :
         189                 : /*
         190                 : ** _PR_InitializeTrace() -- Initialize the trace facility
         191                 : */
         192               0 : static void _PR_InitializeTrace( void )
         193                 : {
         194                 :     /* The lock pointer better be null on this call */
         195               0 :     PR_ASSERT( traceLock == NULL );
         196                 :
         197               0 :     traceLock = PR_NewLock();
         198               0 :     PR_ASSERT( traceLock != NULL );
         199                 :
         200               0 :     PR_Lock( traceLock );
         201                 :
         202               0 :     PR_INIT_CLIST( &qNameList );
         203                 :
         204               0 :     lm = PR_NewLogModule("trace");
         205                 :
         206               0 :     bufSize = DEFAULT_TRACE_BUFSIZE;
         207               0 :     NewTraceBuffer( bufSize );
         208                 :
         209                 :     /* Initialize logging controls */
         210               0 :     logLock = PR_NewLock();
         211               0 :     logCVar = PR_NewCondVar( logLock );
         212                 :
         213               0 :     PR_Unlock( traceLock );
         214                 :     return;
         215                 : } /* end _PR_InitializeTrace() */
         216                 :
         217                 : /*
         218                 : ** Create a Trace Handle
         219                 : */
         220                 : PR_IMPLEMENT(PRTraceHandle)
         221               0 :         PR_CreateTrace(
         222                 :         const char *qName,          /* QName for this trace handle */
         223                 :             const char *rName,          /* RName for this trace handle */
         224                 :             const char *description     /* description for this trace handle */
         225                 : )
         226                 : {
         227                 :     QName   *qnp;
         228                 :     RName   *rnp;
         229               0 :     PRBool  matchQname = PR_FALSE;
         230                 :
         231                 :     /* Self initialize, if necessary */
         232               0 :     if ( traceLock == NULL )
         233               0 :         _PR_InitializeTrace();
         234                 :
         235                 :     /* Validate input arguments */
         236               0 :     PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX );
         237               0 :     PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX );
         238               0 :     PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX );
         239                 :
         240               0 :     PR_LOG( lm, PR_LOG_DEBUG,
         241                 :             ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName));
         242                 :
         243                 :     /* Lock the Facility */
         244               0 :     PR_Lock( traceLock );
         245                 :
         246                 :     /* Do we already have a matching QName? */
         247               0 :     if (!PR_CLIST_IS_EMPTY( &qNameList ))
         248                 :     {
         249               0 :         qnp = (QName *) PR_LIST_HEAD( &qNameList );
         250                 :         do {
         251               0 :             if ( strcmp(qnp->name, qName) == 0)
         252                 :             {
         253               0 :                 matchQname = PR_TRUE;
         254               0 :                 break;
         255                 :             }
         256               0 :             qnp = (QName *)PR_NEXT_LINK( &qnp->link );
         257               0 :         } while( qnp != (QName *)PR_LIST_HEAD( &qNameList ));
         258                 :     }
         259                 :     /*
         260                 :     ** If we did not find a matching QName,
         261                 :     **    allocate one and initialize it.
         262                 :     **    link it onto the qNameList.
         263                 :     **
         264                 :     */
         265               0 :     if ( matchQname != PR_TRUE )
         266                 :     {
         267               0 :         qnp = PR_NEWZAP( QName );
         268               0 :         PR_ASSERT( qnp != NULL );
         269               0 :         PR_INIT_CLIST( &qnp->link );
         270               0 :         PR_INIT_CLIST( &qnp->rNameList );
         271               0 :         strcpy( qnp->name, qName );
         272               0 :         PR_APPEND_LINK( &qnp->link, &qNameList );
         273                 :     }
         274                 :
         275                 :     /* Do we already have a matching RName? */
         276               0 :     if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
         277                 :     {
         278               0 :         rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
         279                 :         do {
         280                 :             /*
         281                 :             ** No duplicate RNames are allowed within a QName
         282                 :             **
         283                 :             */
         284               0 :             PR_ASSERT( strcmp(rnp->name, rName));
         285               0 :             rnp = (RName *)PR_NEXT_LINK( &rnp->link );
         286               0 :         } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList ));
         287                 :     }
         288                 :
         289                 :     /* Get a new RName structure; initialize its members */
         290               0 :     rnp = PR_NEWZAP( RName );
         291               0 :     PR_ASSERT( rnp != NULL );
         292               0 :     PR_INIT_CLIST( &rnp->link );
         293               0 :     strcpy( rnp->name, rName );
         294               0 :     strcpy( rnp->desc, description );
         295               0 :     rnp->lock = PR_NewLock();
         296               0 :     rnp->state = Running;
         297               0 :     if ( rnp->lock == NULL )
         298                 :     {
         299               0 :         PR_ASSERT(0);
         300                 :     }
         301                 :
         302               0 :     PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */
         303               0 :     rnp->qName = qnp;                       /* point the RName to the QName */
         304                 :
         305                 :     /* Unlock the Facility */
         306               0 :     PR_Unlock( traceLock );
         307               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t",
         308                 :         qName, qnp, rName, rnp ));
         309                 :
         310               0 :     return((PRTraceHandle)rnp);
         311                 : } /* end  PR_CreateTrace() */
         312                 :
         313                 : /*
         314                 : **
         315                 : */
         316                 : PR_IMPLEMENT(void)
         317               0 :         PR_DestroyTrace(
         318                 :                 PRTraceHandle handle    /* Handle to be destroyed */
         319                 : )
         320                 : {
         321               0 :     RName   *rnp = (RName *)handle;
         322               0 :     QName   *qnp = rnp->qName;
         323                 :
         324               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s",
         325                 :         qnp->name, rnp->name));
         326                 :
         327                 :     /* Lock the Facility */
         328               0 :     PR_Lock( traceLock );
         329                 :
         330                 :     /*
         331                 :     ** Remove RName from the list of RNames in QName
         332                 :     ** and free RName
         333                 :     */
         334               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p",
         335                 :         rnp->name, rnp));
         336               0 :     PR_REMOVE_LINK( &rnp->link );
         337               0 :     PR_Free( rnp->lock );
         338               0 :     PR_DELETE( rnp );
         339                 :
         340                 :     /*
         341                 :     ** If this is the last RName within QName
         342                 :     **   remove QName from the qNameList and free it
         343                 :     */
         344               0 :     if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
         345                 :     {
         346               0 :         PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p",
         347                 :             qnp->name, qnp));
         348               0 :         PR_REMOVE_LINK( &qnp->link );
         349               0 :         PR_DELETE( qnp );
         350                 :     }
         351                 :
         352                 :     /* Unlock the Facility */
         353               0 :     PR_Unlock( traceLock );
         354                 :     return;
         355                 : } /* end PR_DestroyTrace()  */
         356                 :
         357                 : /*
         358                 : ** Create a TraceEntry in the trace buffer
         359                 : */
         360                 : PR_IMPLEMENT(void)
         361               0 :         PR_Trace(
         362                 :         PRTraceHandle handle,       /* use this trace handle */
         363                 :             PRUint32    userData0,      /* User supplied data word 0 */
         364                 :             PRUint32    userData1,      /* User supplied data word 1 */
         365                 :             PRUint32    userData2,      /* User supplied data word 2 */
         366                 :             PRUint32    userData3,      /* User supplied data word 3 */
         367                 :             PRUint32    userData4,      /* User supplied data word 4 */
         368                 :             PRUint32    userData5,      /* User supplied data word 5 */
         369                 :             PRUint32    userData6,      /* User supplied data word 6 */
         370                 :             PRUint32    userData7       /* User supplied data word 7 */
         371                 : )
         372                 : {
         373                 :     PRTraceEntry   *tep;
         374                 :     PRInt32         mark;
         375                 :
         376               0 :     if ( (traceState == Suspended )
         377               0 :         || ( ((RName *)handle)->state == Suspended ))
         378               0 :         return;
         379                 :
         380                 :     /*
         381                 :     ** Get the next trace entry slot w/ minimum delay
         382                 :     */
         383               0 :     PR_Lock( traceLock );
         384                 :
         385               0 :     tep = &tBuf[next++];
         386               0 :     if ( next > last )
         387               0 :         next = 0;
         388               0 :     if ( fetchLostData == PR_FALSE && next == fetchLastSeen )
         389               0 :         fetchLostData = PR_TRUE;
         390                 :
         391               0 :     mark = next;
         392                 :
         393               0 :     PR_Unlock( traceLock );
         394                 :
         395                 :     /*
         396                 :     ** We have a trace entry. Fill it in.
         397                 :     */
         398               0 :     tep->thread = PR_GetCurrentThread();
         399               0 :     tep->handle = handle;
         400               0 :     tep->time   = PR_Now();
         401               0 :     tep->userData[0] = userData0;
         402               0 :     tep->userData[1] = userData1;
         403               0 :     tep->userData[2] = userData2;
         404               0 :     tep->userData[3] = userData3;
         405               0 :     tep->userData[4] = userData4;
         406               0 :     tep->userData[5] = userData5;
         407               0 :     tep->userData[6] = userData6;
         408               0 :     tep->userData[7] = userData7;
         409                 :
         410                 :     /* When buffer segment is full, signal trace log thread to run */
         411               0 :     if (( mark % logEntriesPerSegment) == 0 )
         412                 :     {
         413               0 :         PR_Lock( logLock );
         414               0 :         logCount++;
         415               0 :         PR_NotifyCondVar( logCVar );
         416               0 :         PR_Unlock( logLock );
         417                 :         /*
         418                 :         ** Gh0D! This is awful!
         419                 :         ** Anyway, to minimize lost trace data segments,
         420                 :         ** I inserted the PR_Sleep(0) to cause a context switch
         421                 :         ** so that the log thread could run.
         422                 :         ** I know, it perturbs the universe and may cause
         423                 :         ** funny things to happen in the optimized builds.
         424                 :         ** Take it out, lose data; leave it in risk Heisenberg.
         425                 :         */
         426                 :         /* PR_Sleep(0); */
         427                 :     }
         428                 :
         429               0 :     return;
         430                 : } /* end PR_Trace() */
         431                 :
         432                 : /*
         433                 : **
         434                 : */
         435                 : PR_IMPLEMENT(void)
         436               0 :         PR_SetTraceOption(
         437                 :             PRTraceOption command,  /* One of the enumerated values */
         438                 :             void *value             /* command value or NULL */
         439                 : )
         440                 : {
         441                 :     RName * rnp;
         442                 :
         443               0 :     switch ( command )
         444                 :     {
         445                 :         case PRTraceBufSize :
         446               0 :             PR_Lock( traceLock );
         447               0 :             PR_Free( tBuf );
         448               0 :             bufSize = *(PRInt32 *)value;
         449               0 :             NewTraceBuffer( bufSize );
         450               0 :             PR_Unlock( traceLock );
         451               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         452                 :                 ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize));
         453               0 :             break;
         454                 :
         455                 :         case PRTraceEnable :
         456               0 :             rnp = *(RName **)value;
         457               0 :             rnp->state = Running;
         458               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         459                 :                 ("PRSetTraceOption: PRTraceEnable: %p", rnp));
         460               0 :             break;
         461                 :
         462                 :         case PRTraceDisable :
         463               0 :             rnp = *(RName **)value;
         464               0 :             rnp->state = Suspended;
         465               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         466                 :                 ("PRSetTraceOption: PRTraceDisable: %p", rnp));
         467               0 :             break;
         468                 :
         469                 :         case PRTraceSuspend :
         470               0 :             traceState = Suspended;
         471               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         472                 :                 ("PRSetTraceOption: PRTraceSuspend"));
         473               0 :             break;
         474                 :
         475                 :         case PRTraceResume :
         476               0 :             traceState = Running;
         477               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         478                 :                 ("PRSetTraceOption: PRTraceResume"));
         479               0 :             break;
         480                 :
         481                 :         case PRTraceSuspendRecording :
         482               0 :             PR_Lock( logLock );
         483               0 :             logOrder = LogSuspend;
         484               0 :             PR_NotifyCondVar( logCVar );
         485               0 :             PR_Unlock( logLock );
         486               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         487                 :                 ("PRSetTraceOption: PRTraceSuspendRecording"));
         488               0 :             break;
         489                 :
         490                 :         case PRTraceResumeRecording :
         491               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         492                 :                 ("PRSetTraceOption: PRTraceResumeRecording"));
         493               0 :             if ( logState != LogSuspend )
         494               0 :                 break;
         495               0 :             PR_Lock( logLock );
         496               0 :             logOrder = LogResume;
         497               0 :             PR_NotifyCondVar( logCVar );
         498               0 :             PR_Unlock( logLock );
         499               0 :             break;
         500                 :
         501                 :         case PRTraceStopRecording :
         502               0 :             PR_Lock( logLock );
         503               0 :             logOrder = LogStop;
         504               0 :             PR_NotifyCondVar( logCVar );
         505               0 :             PR_Unlock( logLock );
         506               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         507                 :                 ("PRSetTraceOption: PRTraceStopRecording"));
         508               0 :             break;
         509                 :
         510                 :         case PRTraceLockHandles :
         511               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         512                 :                 ("PRSetTraceOption: PRTraceLockTraceHandles"));
         513               0 :             PR_Lock( traceLock );
         514               0 :             break;
         515                 :
         516                 :         case PRTraceUnLockHandles :
         517               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         518                 :                 ("PRSetTraceOption: PRTraceUnLockHandles"));
         519               0 :             PR_Unlock( traceLock );
         520               0 :             break;
         521                 :
         522                 :         default:
         523               0 :             PR_LOG( lm, PR_LOG_ERROR,
         524                 :                 ("PRSetTraceOption: Invalid command %ld", command ));
         525               0 :             PR_ASSERT( 0 );
         526               0 :             break;
         527                 :     } /* end switch() */
         528                 :     return;
         529                 : } /* end  PR_SetTraceOption() */
         530                 :
         531                 : /*
         532                 : **
         533                 : */
         534                 : PR_IMPLEMENT(void)
         535               0 :         PR_GetTraceOption(
         536                 :         PRTraceOption command,  /* One of the enumerated values */
         537                 :             void *value             /* command value or NULL */
         538                 : )
         539                 : {
         540               0 :     switch ( command )
         541                 :     {
         542                 :         case PRTraceBufSize :
         543               0 :             *((PRInt32 *)value) = bufSize;
         544               0 :             PR_LOG( lm, PR_LOG_DEBUG,
         545                 :                 ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize ));
         546               0 :             break;
         547                 :
         548                 :         default:
         549               0 :             PR_LOG( lm, PR_LOG_ERROR,
         550                 :                 ("PRGetTraceOption: Invalid command %ld", command ));
         551               0 :             PR_ASSERT( 0 );
         552               0 :             break;
         553                 :     } /* end switch() */
         554                 :     return;
         555                 : } /* end PR_GetTraceOption() */
         556                 :
         557                 : /*
         558                 : **
         559                 : */
         560                 : PR_IMPLEMENT(PRTraceHandle)
         561               0 :         PR_GetTraceHandleFromName(
         562                 :         const char *qName,      /* QName search argument */
         563                 :         const char *rName       /* RName search argument */
         564                 : )
         565                 : {
         566                 :     const char    *qn, *rn, *desc;
         567               0 :     PRTraceHandle     qh, rh = NULL;
         568               0 :     RName   *rnp = NULL;
         569                 :
         570               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t"
         571                 :         "QName: %s, RName: %s", qName, rName ));
         572                 :
         573               0 :     qh = PR_FindNextTraceQname( NULL );
         574               0 :     while (qh != NULL)
         575                 :     {
         576               0 :         rh = PR_FindNextTraceRname( NULL, qh );
         577               0 :         while ( rh != NULL )
         578                 :         {
         579               0 :             PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc );
         580               0 :             if ( (strcmp( qName, qn ) == 0)
         581               0 :                 && (strcmp( rName, rn ) == 0 ))
         582                 :             {
         583               0 :                 rnp = (RName *)rh;
         584               0 :                 goto foundIt;
         585                 :             }
         586               0 :             rh = PR_FindNextTraceRname( rh, qh );
         587                 :         }
         588               0 :         qh = PR_FindNextTraceQname( NULL );
         589                 :     }
         590                 :
         591                 : foundIt:
         592               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
         593               0 :     return(rh);
         594                 : } /* end PR_GetTraceHandleFromName() */
         595                 :
         596                 : /*
         597                 : **
         598                 : */
         599                 : PR_IMPLEMENT(void)
         600               0 :         PR_GetTraceNameFromHandle(
         601                 :         PRTraceHandle handle,       /* handle as search argument */
         602                 :             const char **qName,         /* pointer to associated QName */
         603                 :             const char **rName,         /* pointer to associated RName */
         604                 :         const char **description    /* pointer to associated description */
         605                 : )
         606                 : {
         607               0 :     RName   *rnp = (RName *)handle;
         608               0 :     QName   *qnp = rnp->qName;
         609                 :
         610               0 :     *qName = qnp->name;
         611               0 :     *rName = rnp->name;
         612               0 :     *description = rnp->desc;
         613                 :
         614               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: "
         615                 :         "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s",
         616                 :         qnp, rnp, qnp->name, rnp->name, rnp->desc ));
         617                 :
         618                 :     return;
         619                 : } /* end PR_GetTraceNameFromHandle() */
         620                 :
         621                 : /*
         622                 : **
         623                 : */
         624                 : PR_IMPLEMENT(PRTraceHandle)
         625               0 :         PR_FindNextTraceQname(
         626                 :         PRTraceHandle handle
         627                 : )
         628                 : {
         629               0 :     QName *qnp = (QName *)handle;
         630                 :
         631               0 :     if ( PR_CLIST_IS_EMPTY( &qNameList ))
         632               0 :             qnp = NULL;
         633               0 :     else if ( qnp == NULL )
         634               0 :         qnp = (QName *)PR_LIST_HEAD( &qNameList );
         635               0 :     else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
         636               0 :         qnp = NULL;
         637                 :     else
         638               0 :         qnp = (QName *)PR_NEXT_LINK( &qnp->link );
         639                 :
         640               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p",
         641                 :         handle, qnp ));
         642                 :
         643               0 :     return((PRTraceHandle)qnp);
         644                 : } /* end PR_FindNextTraceQname() */
         645                 :
         646                 : /*
         647                 : **
         648                 : */
         649                 : PR_IMPLEMENT(PRTraceHandle)
         650               0 :         PR_FindNextTraceRname(
         651                 :         PRTraceHandle rhandle,
         652                 :         PRTraceHandle qhandle
         653                 : )
         654                 : {
         655               0 :     RName *rnp = (RName *)rhandle;
         656               0 :     QName *qnp = (QName *)qhandle;
         657                 :
         658                 :
         659               0 :     if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
         660               0 :         rnp = NULL;
         661               0 :     else if ( rnp == NULL )
         662               0 :         rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
         663               0 :     else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
         664               0 :         rnp = NULL;
         665                 :     else
         666               0 :         rnp = (RName *)PR_NEXT_LINK( &rnp->link );
         667                 :
         668               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p",
         669                 :         rhandle, qhandle, rnp ));
         670                 :
         671               0 :     return((PRTraceHandle)rnp);
         672                 : } /* end PR_FindNextTraceRname() */
         673                 :
         674                 : /*
         675                 : **
         676                 : */
         677               0 : static PRFileDesc * InitializeRecording( void )
         678                 : {
         679                 :     char    *logFileName;
         680                 :     PRFileDesc  *logFile;
         681                 :
         682                 :     /* Self initialize, if necessary */
         683               0 :     if ( traceLock == NULL )
         684               0 :         _PR_InitializeTrace();
         685                 :
         686               0 :     PR_LOG( lm, PR_LOG_DEBUG,
         687                 :         ("PR_RecordTraceEntries: begins"));
         688                 :
         689               0 :     logLostData = 0; /* reset at entry */
         690               0 :     logState = LogReset;
         691                 :
         692                 : #ifdef XP_UNIX
         693               0 :     if ((getuid() != geteuid()) || (getgid() != getegid())) {
         694               0 :         return NULL;
         695                 :     }
         696                 : #endif /* XP_UNIX */
         697                 :
         698                 :     /* Get the filename for the logfile from the environment */
         699               0 :     logFileName = PR_GetEnv( "NSPR_TRACE_LOG" );
         700               0 :     if ( logFileName == NULL )
         701                 :     {
         702               0 :         PR_LOG( lm, PR_LOG_ERROR,
         703                 :             ("RecordTraceEntries: Environment variable not defined. Exiting"));
         704               0 :         return NULL;
         705                 :     }
         706                 :
         707                 :     /* Open the logfile */
         708               0 :     logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 );
         709               0 :     if ( logFile == NULL )
         710                 :     {
         711               0 :         PR_LOG( lm, PR_LOG_ERROR,
         712                 :             ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld",
         713                 :                 logFileName, PR_GetOSError()));
         714               0 :         return NULL;
         715                 :     }
         716               0 :     return logFile;
         717                 : } /* end InitializeRecording() */
         718                 :
         719                 : /*
         720                 : **
         721                 : */
         722               0 : static void ProcessOrders( void )
         723                 : {
         724               0 :     switch ( logOrder )
         725                 :     {
         726                 :     case LogReset :
         727               0 :         logOrder = logState = localState;
         728               0 :         PR_LOG( lm, PR_LOG_DEBUG,
         729                 :             ("RecordTraceEntries: LogReset"));
         730               0 :         break;
         731                 :
         732                 :     case LogSuspend :
         733               0 :         localState = logOrder = logState = LogSuspend;
         734               0 :         PR_LOG( lm, PR_LOG_DEBUG,
         735                 :             ("RecordTraceEntries: LogSuspend"));
         736               0 :         break;
         737                 :
         738                 :     case LogResume :
         739               0 :         localState = logOrder = logState = LogActive;
         740               0 :         PR_LOG( lm, PR_LOG_DEBUG,
         741                 :             ("RecordTraceEntries: LogResume"));
         742               0 :         break;
         743                 :
         744                 :     case LogStop :
         745               0 :         logOrder = logState = LogStop;
         746               0 :         PR_LOG( lm, PR_LOG_DEBUG,
         747                 :             ("RecordTraceEntries: LogStop"));
         748               0 :         break;
         749                 :
         750                 :     default :
         751               0 :         PR_LOG( lm, PR_LOG_ERROR,
         752                 :             ("RecordTraceEntries: Invalid logOrder: %ld", logOrder ));
         753               0 :         PR_ASSERT( 0 );
         754               0 :         break;
         755                 :     } /* end switch() */
         756                 :     return ;
         757                 : } /* end ProcessOrders() */
         758                 :
         759                 : /*
         760                 : **
         761                 : */
         762               0 : static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount )
         763                 : {
         764                 :     PRInt32 rc;
         765                 :
         766                 :
         767               0 :     PR_LOG( lm, PR_LOG_ERROR,
         768                 :         ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount));
         769               0 :     rc = PR_Write( logFile, buf , amount );
         770               0 :     if ( rc == -1 )
         771               0 :         PR_LOG( lm, PR_LOG_ERROR,
         772                 :             ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() ));
         773               0 :     else if ( rc != amount )
         774               0 :         PR_LOG( lm, PR_LOG_ERROR,
         775                 :             ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc));
         776                 :     else
         777               0 :         PR_LOG( lm, PR_LOG_DEBUG,
         778                 :             ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount));
         779                 :
         780                 :     return;
         781                 : } /* end WriteTraceSegment() */
         782                 :
         783                 : /*
         784                 : **
         785                 : */
         786                 : PR_IMPLEMENT(void)
         787               0 :         PR_RecordTraceEntries(
         788                 :         void
         789                 : )
         790                 : {
         791                 :     PRFileDesc  *logFile;
         792                 :     PRInt32     lostSegments;
         793               0 :     PRInt32     currentSegment = 0;
         794                 :     void        *buf;
         795                 :     PRBool      doWrite;
         796                 :
         797               0 :     logFile = InitializeRecording();
         798               0 :     if ( logFile == NULL )
         799                 :     {
         800               0 :         PR_LOG( lm, PR_LOG_DEBUG,
         801                 :             ("PR_RecordTraceEntries: Failed to initialize"));
         802               0 :         return;
         803                 :     }
         804                 :
         805                 :     /* Do this until told to stop */
         806               0 :     while ( logState != LogStop )
         807                 :     {
         808                 :
         809               0 :         PR_Lock( logLock );
         810                 :
         811               0 :         while ( (logCount == 0) && ( logOrder == logState ) )
         812               0 :             PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT );
         813                 :
         814                 :         /* Handle state transitions */
         815               0 :         if ( logOrder != logState )
         816               0 :             ProcessOrders();
         817                 :
         818                 :         /* recalculate local controls */
         819               0 :         if ( logCount )
         820                 :         {
         821               0 :             lostSegments = logCount - logSegments;
         822               0 :             if ( lostSegments > 0 )
         823                 :             {
         824               0 :                 logLostData += ( logCount - logSegments );
         825               0 :                 logCount = (logCount % logSegments);
         826               0 :                 currentSegment = logCount;
         827               0 :                 PR_LOG( lm, PR_LOG_DEBUG,
         828                 :                     ("PR_RecordTraceEntries: LostData segments: %ld", logLostData));
         829                 :             }
         830                 :             else
         831                 :             {
         832               0 :                 logCount--;
         833                 :             }
         834                 :
         835               0 :             buf = tBuf + ( logEntriesPerSegment * currentSegment );
         836               0 :             if (++currentSegment >= logSegments )
         837               0 :                 currentSegment = 0;
         838               0 :             doWrite = PR_TRUE;
         839                 :         }
         840                 :         else
         841               0 :             doWrite = PR_FALSE;
         842                 :
         843               0 :         PR_Unlock( logLock );
         844                 :
         845               0 :         if ( doWrite == PR_TRUE )
         846                 :         {
         847               0 :             if ( localState != LogSuspend )
         848               0 :                 WriteTraceSegment( logFile, buf, logSegSize );
         849                 :             else
         850               0 :                 PR_LOG( lm, PR_LOG_DEBUG,
         851                 :                     ("RecordTraceEntries: PR_Write(): is suspended" ));
         852                 :         }
         853                 :
         854                 :     } /* end while(logState...) */
         855                 :
         856               0 :     PR_Close( logFile );
         857               0 :     PR_LOG( lm, PR_LOG_DEBUG,
         858                 :         ("RecordTraceEntries: exiting"));
         859               0 :     return;
         860                 : } /* end  PR_RecordTraceEntries() */
         861                 :
         862                 : /*
         863                 : **
         864                 : */
         865                 : PR_IMPLEMENT(PRIntn)
         866               0 :     PR_GetTraceEntries(
         867                 :         PRTraceEntry    *buffer,    /* where to write output */
         868                 :         PRInt32         count,      /* number to get */
         869                 :         PRInt32         *found      /* number you got */
         870                 : )
         871                 : {
         872                 :     PRInt32 rc;
         873               0 :     PRInt32 copied = 0;
         874                 :
         875               0 :     PR_Lock( traceLock );
         876                 :
         877                 :     /*
         878                 :     ** Depending on where the LastSeen and Next indices are,
         879                 :     ** copy the trace buffer in one or two pieces.
         880                 :     */
         881               0 :     PR_LOG( lm, PR_LOG_ERROR,
         882                 :         ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen));
         883                 :
         884               0 :     if ( fetchLastSeen <= next )
         885                 :     {
         886               0 :         while (( count-- > 0 ) && (fetchLastSeen < next ))
         887                 :         {
         888               0 :             *(buffer + copied++) = *(tBuf + fetchLastSeen++);
         889                 :         }
         890               0 :         PR_LOG( lm, PR_LOG_ERROR,
         891                 :             ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
         892                 :     }
         893                 :     else /* copy in 2 parts */
         894                 :     {
         895               0 :         while ( count-- > 0  && fetchLastSeen <= last )
         896                 :         {
         897               0 :             *(buffer + copied++) = *(tBuf + fetchLastSeen++);
         898                 :         }
         899               0 :         fetchLastSeen = 0;
         900                 :
         901               0 :         PR_LOG( lm, PR_LOG_ERROR,
         902                 :             ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
         903                 :
         904               0 :         while ( count-- > 0  && fetchLastSeen < next )
         905                 :         {
         906               0 :             *(buffer + copied++) = *(tBuf + fetchLastSeen++);
         907                 :         }
         908               0 :         PR_LOG( lm, PR_LOG_ERROR,
         909                 :             ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
         910                 :     }
         911                 :
         912               0 :     *found = copied;
         913               0 :     rc = ( fetchLostData == PR_TRUE )? 1 : 0;
         914               0 :     fetchLostData = PR_FALSE;
         915                 :
         916               0 :     PR_Unlock( traceLock );
         917               0 :     return rc;
         918                 : } /* end PR_GetTraceEntries() */
         919                 :
         920                 : /* end prtrace.c */

Generated by: LCOV version 1.7