summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2025-08-01 19:03:16 -0400
committerRusty Wagner <rusty.wagner@gmail.com>2025-08-01 20:56:38 -0400
commitbe8c0c03e5d784ff7d2909d120cda6566ac2cea6 (patch)
tree8e463b2dd62f2478529ea25e3f6599f12007d394
parent15c635b873105eda2861430d062ea3f6bdfe9d9b (diff)
Add log functions for logging the current stack trace without an active exception
-rw-r--r--binaryninjaapi.h440
-rw-r--r--log.cpp232
-rw-r--r--python/log.py101
3 files changed, 648 insertions, 125 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 2173dd19..344fb03e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -813,21 +813,104 @@ namespace BinaryNinja {
BN_PRINTF_ATTRIBUTE(2, 3)
void LogAlertForException(const std::exception& e, const char* fmt, ...);
+ /*! Logs to the error console with the given BNLogLevel.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param level BNLogLevel debug log level
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(2, 3)
+ void LogWithStackTrace(BNLogLevel level, const char* fmt, ...);
+
+ /*! LogTraceWithStackTrace only writes text to the error console if the console is set to log level: DebugLog
+ Log level and the build is not a DEBUG build (i.e. the preprocessor directive _DEBUG is defined)
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(1, 2)
+ void LogTraceWithStackTrace(const char* fmt, ...);
+
+ /*! LogDebugWithStackTrace only writes text to the error console if the console is set to log level: DebugLog
+ Log level DebugLog is the most verbose logging level in release builds.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(1, 2)
+ void LogDebugWithStackTrace(const char* fmt, ...);
+
+ /*! LogInfoWithStackTrace always writes text to the error console, and corresponds to the log level: InfoLog.
+ Log level InfoLog is the second most verbose logging level.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(1, 2)
+ void LogInfoWithStackTrace(const char* fmt, ...);
+
+ /*! LogWarnWithStackTrace writes text to the error console including a warning icon,
+ and also shows a warning icon in the bottom pane. LogWarn corresponds to the log level: WarningLog.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(1, 2)
+ void LogWarnWithStackTrace(const char* fmt, ...);
+
+ /*! LogErrorWithStackTrace writes text to the error console and pops up the error console. Additionally,
+ Errors in the console log include a error icon. LogError corresponds to the log level: ErrorLog.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(1, 2)
+ void LogErrorWithStackTrace(const char* fmt, ...);
+
+ /*! LogAlertWithStackTrace pops up a message box displaying the alert message and logs to the error console.
+ LogAlert corresponds to the log level: AlertLog.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ BN_PRINTF_ATTRIBUTE(1, 2)
+ void LogAlertWithStackTrace(const char* fmt, ...);
+
// Implementation detail
void LogFV(BNLogLevel level, fmt::string_view format, fmt::format_args args);
void LogTraceFV(fmt::string_view format, fmt::format_args args);
- void LogDebugFV(fmt::string_view format, fmt::format_args args);
- void LogInfoFV(fmt::string_view format, fmt::format_args args);
- void LogWarnFV(fmt::string_view format, fmt::format_args args);
- void LogErrorFV(fmt::string_view format, fmt::format_args args);
- void LogAlertFV(fmt::string_view format, fmt::format_args args);
void LogForExceptionFV(BNLogLevel level, const std::exception& e, fmt::string_view format, fmt::format_args args);
void LogTraceForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogDebugForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogInfoForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogWarnForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogErrorForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogAlertForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
+ void LogWithStackTraceFV(BNLogLevel level, fmt::string_view format, fmt::format_args args);
+ void LogTraceWithStackTraceFV(fmt::string_view format, fmt::format_args args);
/*! Logs to the error console with the given BNLogLevel.
@@ -874,7 +957,7 @@ namespace BinaryNinja {
template<typename... T>
void LogDebugF(fmt::format_string<T...> format, T&&... args)
{
- LogDebugFV(format, fmt::make_format_args(args...));
+ LogFV(DebugLog, format, fmt::make_format_args(args...));
}
/*! LogInfo always writes text to the error console, and corresponds to the log level: InfoLog.
@@ -890,7 +973,7 @@ namespace BinaryNinja {
template<typename... T>
void LogInfoF(fmt::format_string<T...> format, T&&... args)
{
- LogInfoFV(format, fmt::make_format_args(args...));
+ LogFV(InfoLog, format, fmt::make_format_args(args...));
}
/*! LogWarn writes text to the error console including a warning icon,
@@ -906,7 +989,7 @@ namespace BinaryNinja {
template<typename... T>
void LogWarnF(fmt::format_string<T...> format, T&&... args)
{
- LogWarnFV(format, fmt::make_format_args(args...));
+ LogFV(WarningLog, format, fmt::make_format_args(args...));
}
/*! LogError writes text to the error console and pops up the error console. Additionally,
@@ -922,7 +1005,7 @@ namespace BinaryNinja {
template<typename... T>
void LogErrorF(fmt::format_string<T...> format, T&&... args)
{
- LogErrorFV(format, fmt::make_format_args(args...));
+ LogFV(ErrorLog, format, fmt::make_format_args(args...));
}
/*! LogAlert pops up a message box displaying the alert message and logs to the error console.
@@ -938,7 +1021,7 @@ namespace BinaryNinja {
template<typename... T>
void LogAlertF(fmt::format_string<T...> format, T&&... args)
{
- LogAlertFV(format, fmt::make_format_args(args...));
+ LogFV(AlertLog, format, fmt::make_format_args(args...));
}
/*! Logs to the error console with the given BNLogLevel.
@@ -955,7 +1038,7 @@ namespace BinaryNinja {
template <typename... T>
void LogForExceptionF(BNLogLevel level, const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogWithForExceptionFV(level, e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(level, e, format, fmt::make_format_args(args...));
}
/*! LogTraceForExceptionF only writes text to the error console if the console is set to log level: DebugLog
@@ -989,7 +1072,7 @@ namespace BinaryNinja {
template <typename... T>
void LogDebugForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogDebugForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(DebugLog, e, format, fmt::make_format_args(args...));
}
/*! LogInfoForExceptionF always writes text to the error console, and corresponds to the log level: InfoLog.
@@ -1006,7 +1089,7 @@ namespace BinaryNinja {
template <typename... T>
void LogInfoForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogInfoForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(InfoLog, e, format, fmt::make_format_args(args...));
}
/*! LogWarnForExceptionF writes text to the error console including a warning icon,
@@ -1023,7 +1106,7 @@ namespace BinaryNinja {
template <typename... T>
void LogWarnForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogWarnForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(WarningLog, e, format, fmt::make_format_args(args...));
}
/*! LogErrorForExceptionF writes text to the error console and pops up the error console. Additionally,
@@ -1040,7 +1123,7 @@ namespace BinaryNinja {
template <typename... T>
void LogErrorForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogErrorForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(ErrorLog, e, format, fmt::make_format_args(args...));
}
/*! LogAlertForExceptionF pops up a message box displaying the alert message and logs to the error console.
@@ -1057,7 +1140,119 @@ namespace BinaryNinja {
template <typename... T>
void LogAlertForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogAlertForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(AlertLog, e, format, fmt::make_format_args(args...));
+ }
+
+ /*! Logs to the error console with the given BNLogLevel.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param level BNLogLevel debug log level
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogWithStackTraceF(BNLogLevel level, fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithWithStackTraceFV(level, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogTraceWithStackTraceF only writes text to the error console if the console is set to log level: DebugLog
+ Log level and the build is not a DEBUG build (i.e. the preprocessor directive _DEBUG is defined)
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogTraceWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogTraceWithStackTraceFV(format, fmt::make_format_args(args...));
+ }
+
+ /*! LogDebugWithStackTraceF only writes text to the error console if the console is set to log level: DebugLog
+ Log level DebugLog is the most verbose logging level in release builds.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogDebugWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(DebugLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogInfoWithStackTraceF always writes text to the error console, and corresponds to the log level: InfoLog.
+ Log level InfoLog is the second most verbose logging level.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogInfoWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(InfoLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogWarnWithStackTraceF writes text to the error console including a warning icon,
+ and also shows a warning icon in the bottom pane. LogWarn corresponds to the log level: WarningLog.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogWarnWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(WarningLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogErrorWithStackTraceF writes text to the error console and pops up the error console. Additionally,
+ Errors in the console log include a error icon. LogError corresponds to the log level: ErrorLog.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogErrorWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(ErrorLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogAlertWithStackTraceF pops up a message box displaying the alert message and logs to the error console.
+ LogAlert corresponds to the log level: AlertLog.
+
+ @threadsafe
+
+ \ingroup logging
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogAlertWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(AlertLog, format, fmt::make_format_args(args...));
}
/*! Redirects the minimum level passed to standard out
@@ -1112,20 +1307,11 @@ namespace BinaryNinja {
void LogFV(BNLogLevel level, fmt::string_view format, fmt::format_args args);
void LogTraceFV(fmt::string_view format, fmt::format_args args);
- void LogDebugFV(fmt::string_view format, fmt::format_args args);
- void LogInfoFV(fmt::string_view format, fmt::format_args args);
- void LogWarnFV(fmt::string_view format, fmt::format_args args);
- void LogErrorFV(fmt::string_view format, fmt::format_args args);
- void LogAlertFV(fmt::string_view format, fmt::format_args args);
-
void LogForExceptionFV(
BNLogLevel level, const std::exception& e, fmt::string_view format, fmt::format_args args);
void LogTraceForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogDebugForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogInfoForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogWarnForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogErrorForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
- void LogAlertForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args);
+ void LogWithStackTraceFV(BNLogLevel level, fmt::string_view format, fmt::format_args args);
+ void LogTraceWithStackTraceFV(fmt::string_view format, fmt::format_args args);
public:
Logger(BNLogger* logger);
@@ -1302,6 +1488,76 @@ namespace BinaryNinja {
@threadsafe
\param level BNLogLevel debug log level
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogWithStackTrace(BNLogLevel level, const char* fmt, ...);
+
+ /*! LogTraceWithStackTrace only writes text to the error console if the console is set to log level:
+ DebugLog Log level and the build is not a DEBUG build (i.e. the preprocessor directive _DEBUG is defined)
+
+ @threadsafe
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogTraceWithStackTrace(const char* fmt, ...);
+
+ /*! LogDebugWithStackTrace only writes text to the error console if the console is set to log level:
+ DebugLog Log level DebugLog is the most verbose logging level in release builds.
+
+ @threadsafe
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogDebugWithStackTrace(const char* fmt, ...);
+
+ /*! LogInfoWithStackTrace always writes text to the error console, and corresponds to the log level:
+ InfoLog. Log level InfoLog is the second most verbose logging level.
+
+ @threadsafe
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogInfoWithStackTrace(const char* fmt, ...);
+
+ /*! LogWarnWithStackTrace writes text to the error console including a warning icon,
+ and also shows a warning icon in the bottom pane. LogWarn corresponds to the log level: WarningLog.
+
+ @threadsafe
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogWarnWithStackTrace(const char* fmt, ...);
+
+ /*! LogErrorWithStackTrace writes text to the error console and pops up the error console. Additionally,
+ Errors in the console log include a error icon. LogError corresponds to the log level: ErrorLog.
+
+ @threadsafe
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogErrorWithStackTrace(const char* fmt, ...);
+
+ /*! LogAlertWithStackTrace pops up a message box displaying the alert message and logs to the error console.
+ LogAlert corresponds to the log level: AlertLog.
+
+ @threadsafe
+
+ \param fmt C-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ void LogAlertWithStackTrace(const char* fmt, ...);
+
+ /*! Logs to the error console with the given BNLogLevel.
+
+ @threadsafe
+
+ \param level BNLogLevel debug log level
\param format fmt-style format string.
\param ... Variable arguments corresponding to the format string.
*/
@@ -1336,7 +1592,7 @@ namespace BinaryNinja {
template<typename... T>
void LogDebugF(fmt::format_string<T...> format, T&&... args)
{
- LogDebugFV(format, fmt::make_format_args(args...));
+ LogFV(DebugLog, format, fmt::make_format_args(args...));
}
/*! LogInfo always writes text to the error console, and corresponds to the log level: InfoLog.
@@ -1350,7 +1606,7 @@ namespace BinaryNinja {
template<typename... T>
void LogInfoF(fmt::format_string<T...> format, T&&... args)
{
- LogInfoFV(format, fmt::make_format_args(args...));
+ LogFV(InfoLog, format, fmt::make_format_args(args...));
}
/*! LogWarn writes text to the error console including a warning icon,
@@ -1364,7 +1620,7 @@ namespace BinaryNinja {
template<typename... T>
void LogWarnF(fmt::format_string<T...> format, T&&... args)
{
- LogWarnFV(format, fmt::make_format_args(args...));
+ LogFV(WarningLog, format, fmt::make_format_args(args...));
}
/*! LogError writes text to the error console and pops up the error console. Additionally,
@@ -1378,7 +1634,7 @@ namespace BinaryNinja {
template<typename... T>
void LogErrorF(fmt::format_string<T...> format, T&&... args)
{
- LogErrorFV(format, fmt::make_format_args(args...));
+ LogFV(ErrorLog, format, fmt::make_format_args(args...));
}
/*! LogAlert pops up a message box displaying the alert message and logs to the error console.
@@ -1392,7 +1648,7 @@ namespace BinaryNinja {
template<typename... T>
void LogAlertF(fmt::format_string<T...> format, T&&... args)
{
- LogAlertFV(format, fmt::make_format_args(args...));
+ LogFV(AlertLog, format, fmt::make_format_args(args...));
}
/*! Logs to the error console with the given BNLogLevel and a stack trace.
@@ -1408,7 +1664,7 @@ namespace BinaryNinja {
void LogForExceptionF(
BNLogLevel level, const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogWithForExceptionFV(level, e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(level, e, format, fmt::make_format_args(args...));
}
/*! LogTraceForExceptionF only writes text to the error console if the console is set to log level:
@@ -1438,7 +1694,7 @@ namespace BinaryNinja {
template <typename... T>
void LogDebugForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogDebugForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(DebugLog, e, format, fmt::make_format_args(args...));
}
/*! LogInfoForExceptionF always writes text to the error console, and corresponds to the log level:
@@ -1453,7 +1709,7 @@ namespace BinaryNinja {
template <typename... T>
void LogInfoForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogInfoForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(InfoLog, e, format, fmt::make_format_args(args...));
}
/*! LogWarnForExceptionF writes text to the error console including a warning icon,
@@ -1468,7 +1724,7 @@ namespace BinaryNinja {
template <typename... T>
void LogWarnForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogWarnForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(WarningLog, e, format, fmt::make_format_args(args...));
}
/*! LogErrorForExceptionF writes text to the error console and pops up the error console. Additionally,
@@ -1483,7 +1739,7 @@ namespace BinaryNinja {
template <typename... T>
void LogErrorForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogErrorForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(ErrorLog, e, format, fmt::make_format_args(args...));
}
/*! LogAlertForExceptionF pops up a message box displaying the alert message and logs to the error
@@ -1498,7 +1754,105 @@ namespace BinaryNinja {
template <typename... T>
void LogAlertForExceptionF(const std::exception& e, fmt::format_string<T...> format, T&&... args)
{
- LogAlertForExceptionFV(e, format, fmt::make_format_args(args...));
+ LogForExceptionFV(AlertLog, e, format, fmt::make_format_args(args...));
+ }
+
+ /*! Logs to the error console with the given BNLogLevel and a stack trace.
+
+ @threadsafe
+
+ \param level BNLogLevel debug log level
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogWithStackTraceF(BNLogLevel level, fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(level, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogTraceWithStackTraceF only writes text to the error console if the console is set to log level:
+ DebugLog Log level and the build is not a DEBUG build (i.e. the preprocessor directive _DEBUG is defined)
+
+ @threadsafe
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogTraceWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogTraceWithStackTraceFV(format, fmt::make_format_args(args...));
+ }
+
+ /*! LogDebugWithStackTraceF only writes text to the error console if the console is set to log level:
+ DebugLog Log level DebugLog is the most verbose logging level in release builds.
+
+ @threadsafe
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogDebugWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(DebugLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogInfoWithStackTraceF always writes text to the error console, and corresponds to the log level:
+ InfoLog. Log level InfoLog is the second most verbose logging level.
+
+ @threadsafe
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogInfoWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(InfoLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogWarnWithStackTraceF writes text to the error console including a warning icon,
+ and also shows a warning icon in the bottom pane. LogWarn corresponds to the log level: WarningLog.
+
+ @threadsafe
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogWarnWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(WarningLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogErrorWithStackTraceF writes text to the error console and pops up the error console. Additionally,
+ Errors in the console log include a error icon. LogError corresponds to the log level: ErrorLog.
+
+ @threadsafe
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogErrorWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(ErrorLog, format, fmt::make_format_args(args...));
+ }
+
+ /*! LogAlertWithStackTraceF pops up a message box displaying the alert message and logs to the error
+ console. LogAlert corresponds to the log level: AlertLog.
+
+ @threadsafe
+
+ \param format fmt-style format string.
+ \param ... Variable arguments corresponding to the format string.
+ */
+ template <typename... T>
+ void LogAlertWithStackTraceF(fmt::format_string<T...> format, T&&... args)
+ {
+ LogWithStackTraceFV(AlertLog, format, fmt::make_format_args(args...));
}
/*! Get the name registered for this Logger
diff --git a/log.cpp b/log.cpp
index 709ad112..2329e503 100644
--- a/log.cpp
+++ b/log.cpp
@@ -161,6 +161,49 @@ static void PerformLogForException(size_t session, BNLogLevel level, const strin
}
+static void PerformLogWithStackTrace(size_t session, BNLogLevel level, const string& logger_name, size_t tid,
+ const char* fmt, va_list args)
+{
+ #if defined(_MSC_VER)
+ int len = _vscprintf(fmt, args);
+ if (len < 0)
+ return;
+ char* msg = (char*)malloc(len + 1);
+ if (!msg)
+ return;
+ if (vsnprintf(msg, len + 1, fmt, args) >= 0)
+ {
+ char* stackTrace = BNGetCurrentStackTraceString();
+ if (stackTrace)
+ {
+ BNLogWithStackTrace(session, level, logger_name.c_str(), tid, stackTrace, "%s", msg);
+ BNFreeString(stackTrace);
+ }
+ else
+ {
+ BNLog(session, level, logger_name.c_str(), tid, "%s", msg);
+ }
+ }
+ free(msg);
+ #else
+ char* msg;
+ if (vasprintf(&msg, fmt, args) < 0)
+ return;
+ char* stackTrace = BNGetCurrentStackTraceString();
+ if (stackTrace)
+ {
+ BNLogWithStackTrace(session, level, logger_name.c_str(), tid, stackTrace, "%s", msg);
+ BNFreeString(stackTrace);
+ }
+ else
+ {
+ BNLog(session, level, logger_name.c_str(), tid, "%s", msg);
+ }
+ free(msg);
+ #endif
+}
+
+
void BinaryNinja::Log(BNLogLevel level, const char* fmt, ...)
{
va_list args;
@@ -291,102 +334,111 @@ void BinaryNinja::LogAlertForException(const std::exception& e, const char* fmt,
}
-void BinaryNinja::LogFV(BNLogLevel level, fmt::string_view format, fmt::format_args args)
-{
- std::string value = fmt::vformat(format, args);
- Log(level, "%s", value.c_str());
-}
-
-
-void BinaryNinja::LogTraceFV(fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogWithStackTrace(BNLogLevel level, const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogTrace("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, level, "", 0, fmt, args);
+ va_end(args);
}
-void BinaryNinja::LogDebugFV(fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogTraceWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogDebug("%s", value.c_str());
+ #ifdef _DEBUG
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, DebugLog, "", 0, fmt, args);
+ va_end(args);
+ #endif
}
-void BinaryNinja::LogInfoFV(fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogDebugWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogInfo("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, DebugLog, "", 0, fmt, args);
+ va_end(args);
}
-void BinaryNinja::LogWarnFV(fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogInfoWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogWarn("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, InfoLog, "", 0, fmt, args);
+ va_end(args);
}
-void BinaryNinja::LogErrorFV(fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogWarnWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogError("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, WarningLog, "", 0, fmt, args);
+ va_end(args);
}
-void BinaryNinja::LogAlertFV(fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogErrorWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogAlert("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, ErrorLog, "", 0, fmt, args);
+ va_end(args);
}
-void BinaryNinja::LogForExceptionFV(
- BNLogLevel level, const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogAlertWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogForException(level, e, "%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(0, AlertLog, "", 0, fmt, args);
+ va_end(args);
}
-void BinaryNinja::LogTraceForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogFV(BNLogLevel level, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogTraceForException(e, "%s", value.c_str());
+ Log(level, "%s", value.c_str());
}
-void BinaryNinja::LogDebugForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogTraceFV(fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogDebugForException(e, "%s", value.c_str());
+ LogTrace("%s", value.c_str());
}
-void BinaryNinja::LogInfoForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogForExceptionFV(
+ BNLogLevel level, const std::exception& e, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogInfoForException(e, "%s", value.c_str());
+ LogForException(level, e, "%s", value.c_str());
}
-void BinaryNinja::LogWarnForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogTraceForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogWarnForException(e, "%s", value.c_str());
+ LogTraceForException(e, "%s", value.c_str());
}
-void BinaryNinja::LogErrorForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogWithStackTraceFV(BNLogLevel level, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogErrorForException(e, "%s", value.c_str());
+ LogWithStackTrace(level, "%s", value.c_str());
}
-void BinaryNinja::LogAlertForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void BinaryNinja::LogTraceWithStackTraceFV(fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogAlertForException(e, "%s", value.c_str());
+ LogTraceWithStackTrace("%s", value.c_str());
}
@@ -567,102 +619,118 @@ void Logger::LogAlertForException(const std::exception& e, const char* fmt, ...)
}
-void Logger::LogFV(BNLogLevel level, fmt::string_view format, fmt::format_args args)
-{
- std::string value = fmt::vformat(format, args);
- Log(level, "%s", value.c_str());
-}
-
-
-void Logger::LogTraceFV(fmt::string_view format, fmt::format_args args)
+void Logger::LogWithStackTrace(BNLogLevel level, const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogTrace("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), level, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
}
-void Logger::LogDebugFV(fmt::string_view format, fmt::format_args args)
+void Logger::LogTraceWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogDebug("%s", value.c_str());
+ #ifdef _DEBUG
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), DebugLog, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
+ #endif
}
-void Logger::LogInfoFV(fmt::string_view format, fmt::format_args args)
+void Logger::LogDebugWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogInfo("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), DebugLog, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
}
-void Logger::LogWarnFV(fmt::string_view format, fmt::format_args args)
+void Logger::LogInfoWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogWarn("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), InfoLog, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
}
-void Logger::LogErrorFV(fmt::string_view format, fmt::format_args args)
+void Logger::LogWarnWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogError("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), WarningLog, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
}
-void Logger::LogAlertFV(fmt::string_view format, fmt::format_args args)
+void Logger::LogErrorWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogAlert("%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), ErrorLog, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
}
-void Logger::LogForExceptionFV(
- BNLogLevel level, const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogAlertWithStackTrace(const char* fmt, ...)
{
- std::string value = fmt::vformat(format, args);
- LogForException(level, e, "%s", value.c_str());
+ va_list args;
+ va_start(args, fmt);
+ PerformLogWithStackTrace(
+ GetSessionId(), AlertLog, GetName(), GetThreadId(), fmt::format("{}{}", GetIndent(), fmt).c_str(), args);
+ va_end(args);
}
-void Logger::LogTraceForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogFV(BNLogLevel level, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogTraceForException(e, "%s", value.c_str());
+ Log(level, "%s", value.c_str());
}
-void Logger::LogDebugForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogTraceFV(fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogDebugForException(e, "%s", value.c_str());
+ LogTrace("%s", value.c_str());
}
-void Logger::LogInfoForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogForExceptionFV(
+ BNLogLevel level, const std::exception& e, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogInfoForException(e, "%s", value.c_str());
+ LogForException(level, e, "%s", value.c_str());
}
-void Logger::LogWarnForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogTraceForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogWarnForException(e, "%s", value.c_str());
+ LogTraceForException(e, "%s", value.c_str());
}
-void Logger::LogErrorForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogWithStackTraceFV(BNLogLevel level, fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogErrorForException(e, "%s", value.c_str());
+ LogWithStackTrace(level, "%s", value.c_str());
}
-void Logger::LogAlertForExceptionFV(const std::exception& e, fmt::string_view format, fmt::format_args args)
+void Logger::LogTraceWithStackTraceFV(fmt::string_view format, fmt::format_args args)
{
std::string value = fmt::vformat(format, args);
- LogAlertForException(e, "%s", value.c_str());
+ LogTraceWithStackTrace("%s", value.c_str());
}
diff --git a/python/log.py b/python/log.py
index 678482b6..5c3f8d7d 100644
--- a/python/log.py
+++ b/python/log.py
@@ -233,6 +233,89 @@ def log_alert_for_exception(text: Any, logger: str = ""):
core.BNLogStringWithStackTrace(0, LogLevel.AlertLog, logger, threading.current_thread().ident, traceback.format_exc(), text)
+def log_with_traceback(level: LogLevel, text: Any, logger: str = "", session: int = 0):
+ """
+ ``log_with_traceback`` writes messages to the log console for the given log level, including the current stack trace.
+
+ ============ ======== =======================================================================
+ LogLevelName LogLevel Description
+ ============ ======== =======================================================================
+ DebugLog 0 Logs debugging information messages to the console.
+ InfoLog 1 Logs general information messages to the console.
+ WarningLog 2 Logs message to console with **Warning** icon.
+ ErrorLog 3 Logs message to console with **Error** icon, focusing the error console.
+ AlertLog 4 Logs message to pop up window.
+ ============ ======== =======================================================================
+
+ :param LogLevel level: Log level to use
+ :param str text: message to print
+ :rtype: None
+ """
+ if not isinstance(text, str):
+ text = str(text)
+ core.BNLogStringWithStackTrace(session, level, logger, threading.current_thread().ident, ''.join(traceback.format_stack()), text)
+
+
+def log_debug_with_traceback(text: Any, logger: str = ""):
+ """
+ ``log_debug_with_traceback`` Logs debugging information messages to the console, including the current stack trace.
+
+ :param str text: message to print
+ :rtype: None
+ """
+ if not isinstance(text, str):
+ text = str(text)
+ core.BNLogStringWithStackTrace(0, LogLevel.DebugLog, logger, threading.current_thread().ident, ''.join(traceback.format_stack()), text)
+
+
+def log_info_with_traceback(text: Any, logger: str = ""):
+ """
+ ``log_info_with_traceback`` Logs general information messages to the console, including the current stack trace.
+
+ :param str text: message to print
+ :rtype: None
+ """
+ if not isinstance(text, str):
+ text = str(text)
+ core.BNLogStringWithStackTrace(0, LogLevel.InfoLog, logger, threading.current_thread().ident, ''.join(traceback.format_stack()), text)
+
+
+def log_warn_with_traceback(text: Any, logger: str = ""):
+ """
+ ``log_warn_with_traceback`` Logs message to console, including the current stack trace. When run through the GUI it logs with **Warning** icon.
+
+ :param str text: message to print
+ :rtype: None
+ """
+ if not isinstance(text, str):
+ text = str(text)
+ core.BNLogStringWithStackTrace(0, LogLevel.WarningLog, logger, threading.current_thread().ident, ''.join(traceback.format_stack()), text)
+
+
+def log_error_with_traceback(text: Any, logger: str = ""):
+ """
+ ``log_error_with_traceback`` Logs message to console, including the current stack trace. When run through the GUI it logs with **Error** icon, focusing the error console.
+
+ :param str text: message to print
+ :rtype: None
+ """
+ if not isinstance(text, str):
+ text = str(text)
+ core.BNLogStringWithStackTrace(0, LogLevel.ErrorLog, logger, threading.current_thread().ident, ''.join(traceback.format_stack()), text)
+
+
+def log_alert_with_traceback(text: Any, logger: str = ""):
+ """
+ ``log_alert_with_traceback`` Logs message console, including the current stack trace. A pop up window is created if run through the GUI.
+
+ :param str text: message to print
+ :rtype: None
+ """
+ if not isinstance(text, str):
+ text = str(text)
+ core.BNLogStringWithStackTrace(0, LogLevel.AlertLog, logger, threading.current_thread().ident, ''.join(traceback.format_stack()), text)
+
+
def log_to_stdout(min_level: LogLevel = LogLevel.InfoLog):
"""
``log_to_stdout`` redirects minimum log level to standard out.
@@ -322,3 +405,21 @@ class Logger:
def log_alert_for_exception(self, message: str) -> None:
log_for_exception(LogLevel.AlertLog, message, self.logger_name, self.session_id)
+
+ def log_with_traceback(self, level: LogLevel, message: str) -> None:
+ log_with_traceback(level, message, self.logger_name, self.session_id)
+
+ def log_debug_with_traceback(self, message: str) -> None:
+ log_with_traceback(LogLevel.DebugLog, message, self.logger_name, self.session_id)
+
+ def log_info_with_traceback(self, message: str) -> None:
+ log_with_traceback(LogLevel.InfoLog, message, self.logger_name, self.session_id)
+
+ def log_warn_with_traceback(self, message: str) -> None:
+ log_with_traceback(LogLevel.WarningLog, message, self.logger_name, self.session_id)
+
+ def log_error_with_traceback(self, message: str) -> None:
+ log_with_traceback(LogLevel.ErrorLog, message, self.logger_name, self.session_id)
+
+ def log_alert_with_traceback(self, message: str) -> None:
+ log_with_traceback(LogLevel.AlertLog, message, self.logger_name, self.session_id)