Esempio n. 1
0
void P_CCONV pLog(PLogVerbosityEnum verbosity, 
    PLogChannelEnum channel,
    const pchar *file, 
    puint32 line, 
    const pchar *format, 
    ...)
{
    // The global verbosity value controls which kinds of log can be 
    // printed.
    if (verbosity < g_logVerbosity)
    {
        return ;
    }

    static const pchar *verbosityText[] = 
    {
        "(debug)",
        "(info)",
        "(warning)",
        "(error)",
        "(fatal)",
    };

    va_list arguments;

    va_start(arguments, format);

    if (pstrlen(format) > 200)
    {
        pchar message[1024];
        puint32 nchars = psprintf(message, 1024, 
                "(warning)%s:%d,log buffer for formatting data is too small.",
                __FILE__, __LINE__);
        pLogOutput(P_LOG_CHANNEL2, message, nchars);
    }
    else
    {
        pchar msg[3000]; 
        puint32 nchars;
        if (verbosity == P_LOG_ERROR || verbosity == P_LOG_WARNING)
        {
            pchar fmt[256];
            psprintf(fmt, 256, "%s%s:%d,%s", 
                verbosityText[verbosity], file, line, format);
            nchars = pvsprintf(msg, 3000, fmt, arguments);
        }
        else 
        {
            nchars = pvsprintf(msg, 3000, format, arguments);
        }

        pLogOutput(channel, msg, nchars);
    }

    if (verbosity == P_LOG_FATAL)
    {
        // FIXME: make it more polite
        pabort();
    }
}
Esempio n. 2
0
/**
 * Unconditionally logs an error message.
 *
 * @param msg The message format specification (ala printf).
 * @return ESR_SUCCESS if success, anything else if an error occurs.
 */
ESR_ReturnCode PLogError(const char* msg, ...)
{
  va_list args;
  ESR_ReturnCode rc;
#if defined (ANDROID)
#if defined (HAVE_ANDROID_OS)
  char log_text [2048];
#endif
#endif

  va_start(args, msg);
#if defined (ANDROID)
#if defined (HAVE_ANDROID_OS)
  pvsprintf ( log_text, msg, args);
/* We need to disable some error messages because they are frequently not
 * errors but due to sloppy use of some functions. This prevents us from
 * getting flooded with bad error messages. SteveR
 */
  if ( ( strncmp ( log_text, FILTER_MSG_1, FILTER_MSG_1_SIZE ) != 0 ) &&
    ( strncmp ( log_text, FILTER_MSG_2, FILTER_MSG_2_SIZE ) != 0 ) )
  {
    LOGE ( log_text );
  }
  rc = 0;
#else
  rc = logIt(msg, args, ESR_TRUE);
#endif
#else
  rc = logIt(msg, args, ESR_TRUE);
#endif
  va_end(args);
  
  return rc;
}
Esempio n. 3
0
static ESR_ReturnCode logIt(const LCHAR *format, va_list args, ESR_BOOL showStackTrace)
{
  ESR_ReturnCode rc = ESR_SUCCESS;
  ESR_ReturnCode flushRC = ESR_SUCCESS;
#ifdef USE_STACKTRACE
#define BUFFER_SIZE P_MAX_STACKTRACE + 2000
#else
#define BUFFER_SIZE 2000
#endif
  LCHAR buffer[BUFFER_SIZE] = L("");

  // TODO: Remove once logging subsystem supports "warn" level
  if (strstr(format, "ESR_BUFFER_OVERFLOW")==format)
    return ESR_SUCCESS;
  
#ifdef USE_STACKTRACE
  if (Glogger == NULL)
  {
    /*
     * There are three possible scenerios for why logging would occur although the PLog module
     * is uninitialized:
     *
     * 1) The code fails before PLog is initialized (perhaps in other portable components)
     * 2) The user forgets to initialize the PLog module
     * 3) The code fails after PLog is uninitialized (on shutdown)
     *
     * We do our best by logging any errors but this might result in the memory leak of
     * the PStackTrace module in case 3.
     */
    rc = PStackTraceCreate();
    if (rc != ESR_SUCCESS)
    {
      PLOG_PANIC(L("PStackTraceCreate"), rc);
      goto CLEANUP;
    }
  }
  else
  {
#ifdef USE_THREAD
    rc = PtrdMutexLock(Gmutex);
    if (rc != ESR_SUCCESS)
      return rc;
#endif
  }
  if (locked)
    return ESR_INVALID_STATE;
  locked = ESR_TRUE;
  
  if (GlogFormat & LOG_OUTPUT_FORMAT_DATE_TIME)
  {
    PTimeStamp now;
    struct tm* loctime;
    LCHAR timeStr[TIME_BUF_SIZE];
    size_t timeStrSize;
    
    PTimeStampSet(&now);
    loctime = localtime(&now.secs);
    timeStrSize = LSTRFTIME(timeStr, TIME_BUF_SIZE, TIME_FORMAT, loctime);
    passert(timeStrSize == (TIME_BUF_SIZE - 5));
    psprintf(timeStr + (TIME_BUF_SIZE - 5), ".%03hu", now.msecs);
    
    psprintf(buffer + LSTRLEN(buffer), L("%s|"), timeStr);
    passert(LSTRLEN(buffer) < BUFFER_SIZE);
  }
  
  if (GlogFormat & LOG_OUTPUT_FORMAT_THREAD_ID)
  {
    rc = psprintf(buffer + LSTRLEN(buffer), L("trd=%u|"), PtrdGetCurrentThreadId());
    passert(LSTRLEN(buffer) < BUFFER_SIZE);
  }
  
  if (GlogFormat & LOG_OUTPUT_FORMAT_MODULE_NAME && showStackTrace)
  {
    size_t len = P_MAX_STACKTRACE;
    LCHAR text[P_MAX_STACKTRACE];
    LCHAR* index;
    size_t i;
    
    rc = PStackTraceGetValue((LCHAR*) & text, &len);
    if (rc == ESR_SUCCESS)
    {
      for (i = 0; i < 2; ++i)
      {
        rc = PStackTracePopLevel((LCHAR*) & text);
        if (rc != ESR_SUCCESS)
        {
          PLOG_PANIC(L("PStackTracePopLevel"), rc);
          goto CLEANUP;
        }
      }
      index = text;
      while (index)
      {
        index = LSTRSTR(index, L(" at\n"));
        if (index != NULL)
        {
          *(index + 1) = L('<');
          *(index + 2) = L('-');
          *(index + 3) = L(' ');
        }
      }
    }
    else if (rc == ESR_NOT_SUPPORTED)
      LSTRCPY(text, L(""));
    else if (rc != ESR_SUCCESS)
    {
      PLOG_PANIC(L("PStackTraceGetValue"), rc);
      goto CLEANUP;
    }
    rc = psprintf(buffer + LSTRLEN(buffer), L("Module=%s|"), text);
    passert(LSTRLEN(buffer) < BUFFER_SIZE);
  }
  
  pvsprintf(buffer + LSTRLEN(buffer), format, args);
#else
  pvsprintf(buffer + LSTRLEN(buffer), format, args);
#endif
  passert(LSTRLEN(buffer) < BUFFER_SIZE);
  
  psprintf(buffer + LSTRLEN(buffer), L("\n"));
  passert(LSTRLEN(buffer) < BUFFER_SIZE);
  
  if (Glogger != NULL)
  {
    rc = Glogger->printf(Glogger, L("%s"), buffer);
    if (rc != ESR_SUCCESS)
      goto CLEANUP;
    flushRC = Glogger->flush(Glogger);
  }
  else
  {
    /* We need to log but the logging module is disabled or is locked so we output to stderr instead */
    {
      pfprintf(PSTDERR, L("%s"), buffer);
      pfflush(PSTDERR);
    }
  }
  locked = ESR_FALSE;
#ifdef USE_THREAD
  PtrdMutexUnlock(Gmutex);
#endif
  return flushRC;
CLEANUP:
  if (Glogger != NULL && Glogger->flush != NULL)
    flushRC = Glogger->flush(Glogger);
  locked = ESR_FALSE;
#ifdef USE_THREAD
  PtrdMutexUnlock(Gmutex);
#endif
  return rc != ESR_SUCCESS ? rc : flushRC;
}