[cli] fix crash when full logs is on (#5408)
It is possible that log is printed before the Interpreter (UART or
CONSOLE) object is created when FULL LOGS is enabled. In such case, OT
crashes. This commit fixes this bug.
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index 1f66809..3613659 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -251,6 +251,8 @@
{"version", &Interpreter::ProcessVersion},
};
+Interpreter *Interpreter::sInterpreter = nullptr;
+
Interpreter::Interpreter(Instance *aInstance)
: mUserCommands(nullptr)
, mUserCommandsLength(0)
@@ -4679,8 +4681,12 @@
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
+ VerifyOrExit(Interpreter::IsInitialized(), OT_NOOP);
+
Interpreter::GetInterpreter().OutputFormatV(aFormat, aArgs);
Interpreter::GetInterpreter().OutputFormat("\r\n");
+exit:
+ return;
}
} // namespace Cli
diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp
index 51ae3f5..7b4d9e1 100644
--- a/src/cli/cli.hpp
+++ b/src/cli/cli.hpp
@@ -115,7 +115,20 @@
* @returns A reference to the interpreter object.
*
*/
- static Interpreter &GetInterpreter(void);
+ static Interpreter &GetInterpreter(void)
+ {
+ OT_ASSERT(sInterpreter != nullptr);
+
+ return *sInterpreter;
+ }
+
+ /**
+ * This method returns whether the interpreter is initialized.
+ *
+ * @returns Whether the interpreter is initialized.
+ *
+ */
+ static bool IsInitialized(void) { return sInterpreter != nullptr; }
/**
* This method interprets a CLI command.
@@ -236,6 +249,9 @@
*/
void SetUserCommands(const otCliCommand *aCommands, uint8_t aLength);
+protected:
+ static Interpreter *sInterpreter;
+
private:
enum
{
diff --git a/src/cli/cli_console.cpp b/src/cli/cli_console.cpp
index b2f5647..55ef6bf 100644
--- a/src/cli/cli_console.cpp
+++ b/src/cli/cli_console.cpp
@@ -69,18 +69,11 @@
{
}
-Console *Console::sConsole = nullptr;
-
-Interpreter &Interpreter::GetInterpreter(void)
-{
- return *Console::sConsole;
-}
-
void Console::Initialize(otInstance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext)
{
Instance *instance = static_cast<Instance *>(aInstance);
- sConsole = new (&sCliConsoleRaw) Console(instance, aCallback, aContext);
+ Interpreter::sInterpreter = new (&sCliConsoleRaw) Console(instance, aCallback, aContext);
}
Console::Console(Instance *aInstance, otCliConsoleOutputCallback aCallback, void *aContext)
diff --git a/src/cli/cli_uart.cpp b/src/cli/cli_uart.cpp
index d9dd2bb..b07f32f 100644
--- a/src/cli/cli_uart.cpp
+++ b/src/cli/cli_uart.cpp
@@ -105,17 +105,10 @@
static OT_DEFINE_ALIGNED_VAR(sCliUartRaw, sizeof(Uart), uint64_t);
-Uart *Uart::sUart = nullptr;
-
-Interpreter &Interpreter::GetInterpreter(void)
-{
- return *Uart::sUart;
-}
-
void Uart::Initialize(otInstance *aInstance)
{
- Instance *instance = static_cast<Instance *>(aInstance);
- sUart = new (&sCliUartRaw) Uart(instance);
+ Instance *instance = static_cast<Instance *>(aInstance);
+ Interpreter::sInterpreter = new (&sCliUartRaw) Uart(instance);
}
Uart::Uart(Instance *aInstance)