Bug 1202386: Add logging macros for HAL IPC, r=shuang

The code for packing and unpacking IPC messages does currently not
output detailed error message. This patch adds macros that display
information about the failed operation and arguments. The overhead
of the macros is small and the fast path can be inlined.
This commit is contained in:
Thomas Zimmermann 2015-09-10 11:32:26 +02:00
parent 4d58fd2b5f
commit eaad9f6f6d
2 changed files with 111 additions and 2 deletions

View File

@ -7,23 +7,60 @@
#include "DaemonSocketPDUHelpers.h"
#include <limits>
// Enable this constant to abort Gecko on IPC errors. This is helpful
// for debugging, but should *never* be enabled by default.
#define MOZ_HAL_ABORT_ON_IPC_ERRORS (0)
#ifdef CHROMIUM_LOG
#undef CHROMIUM_LOG
#endif
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args);
#define CHROMIUM_LOG(args...) \
__android_log_print(ANDROID_LOG_INFO, "HAL-IPC", args);
#define CHROMIUM_LOG_VA(fmt, ap) \
__android_log_vprint(ANDROID_LOG_INFO, "HAL-IPC", fmt, ap);
#else
#include <stdio.h>
#define IODEBUG true
#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
#define CHROMIUM_LOG(args...) if (IODEBUG) { printf(args); }
#define CHROMIUM_LOG_VA(fmt, ap) if (IODEBUG) { vprintf(fmt, ap); }
#endif
namespace mozilla {
namespace ipc {
namespace DaemonSocketPDUHelpers {
//
// Logging
//
namespace detail {
void
LogProtocolError(const char* aFmt, ...)
{
va_list ap;
va_start(ap, aFmt);
CHROMIUM_LOG_VA(aFmt, ap);
va_end(ap);
if (MOZ_HAL_ABORT_ON_IPC_ERRORS) {
MOZ_CRASH("HAL IPC protocol error");
}
}
} // namespace detail
//
// Conversion
//

View File

@ -34,6 +34,78 @@ struct DaemonSocketPDUHeader {
namespace DaemonSocketPDUHelpers {
//
// Logging
//
// The HAL IPC logging macros below print clear error messages for
// failed IPC operations. Use |MOZ_HAL_IPC_CONVERT_WARN_IF|,
// |MOZ_HAL_IPC_PACK_WARN_IF| and |MOZ_HAL_IPC_UNPACK_WARN_IF| to
// test for failures when processing PDUs.
//
// All macros accept the test condition as their first argument, and
// additional type information: the convert macro takes the input and
// output types, the pack macro takes the input type, and the unpack
// macro takes output type. All macros return the result of the test
// condition. If the test fails (i.e., the condition is true), they
// output a warning to the log.
//
// Don't call the functions in the detail namespace. They are helpers
// and not for general use.
//
namespace detail {
void
LogProtocolError(const char*, ...);
inline bool
ConvertWarnIfImpl(const char* aFile, unsigned long aLine,
bool aCondition, const char* aExpr, const char* aIn,
const char* aOut)
{
if (MOZ_UNLIKELY(aCondition)) {
LogProtocolError("%s:%d: Convert('%s' to '%s') failed: %s",
aFile, aLine, aIn, aOut, aExpr);
}
return aCondition;
}
inline bool
PackWarnIfImpl(const char* aFile, unsigned long aLine,
bool aCondition, const char* aExpr, const char* aIn)
{
if (MOZ_UNLIKELY(aCondition)) {
LogProtocolError("%s:%d: Pack('%s') failed: %s",
aFile, aLine, aIn, aExpr);
}
return aCondition;
}
inline bool
UnpackWarnIfImpl(const char* aFile, unsigned long aLine,
bool aCondition, const char* aExpr, const char* aOut)
{
if (MOZ_UNLIKELY(aCondition)) {
LogProtocolError("%s:%d: Unpack('%s') failed: %s",
aFile, aLine, aOut, aExpr);
}
return aCondition;
}
} // namespace detail
#define MOZ_HAL_IPC_CONVERT_WARN_IF(condition, in, out) \
::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \
ConvertWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in, #out)
#define MOZ_HAL_IPC_PACK_WARN_IF(condition, in) \
::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \
PackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in)
#define MOZ_HAL_IPC_UNPACK_WARN_IF(condition, out) \
::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \
UnpackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #out)
//
// Conversion
//