This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 7a137f0353 syslog: Don't allow blocking when in signal handler
7a137f0353 is described below
commit 7a137f03539181ef47cad0610e871470b1cfd0ab
Author: Ville Juven <[email protected]>
AuthorDate: Tue Oct 22 16:09:31 2024 +0300
syslog: Don't allow blocking when in signal handler
Blocking while running a signal handler is not advisable, instead write
the log string character by character.
There is also a potential for a deadlock, as discussed in #6618
Note: querying for rtcb->sigdeliver is not 100% ideal, as it only tells
_if_ a signal handler has been queued, not if it is running. However, it
makes syslog safe / usable which is a debug feature anyhow.
---
drivers/syslog/syslog_write.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/syslog/syslog_write.c b/drivers/syslog/syslog_write.c
index 2573384050..f8d8ae739f 100644
--- a/drivers/syslog/syslog_write.c
+++ b/drivers/syslog/syslog_write.c
@@ -37,6 +37,43 @@
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: syslog_safe_to_block
+ *
+ * Description:
+ * Check if it is safe to block for write. If not, the write defaults to a
+ * non-blocking method.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * true if it is safe to block; false otherwise.
+ *
+ ****************************************************************************/
+
+static bool syslog_safe_to_block(void)
+{
+ FAR const struct tcb_s *rtcb;
+
+ /* It's not safe to block in interrupts or when executing the idle loop */
+
+ if (up_interrupt_context() || sched_idletask())
+ {
+ return false;
+ }
+
+ /* It's not safe to block if a signal is being delivered */
+
+ rtcb = nxsched_self();
+ if (rtcb->sigdeliver != NULL)
+ {
+ return false;
+ }
+
+ return true;
+}
+
/****************************************************************************
* Name: syslog_default_write
*
@@ -59,7 +96,7 @@ static ssize_t syslog_default_write(FAR const char *buffer,
size_t buflen)
{
size_t nwritten;
- if (up_interrupt_context() || sched_idletask())
+ if (!syslog_safe_to_block())
{
#ifdef CONFIG_SYSLOG_INTBUFFER
if (up_interrupt_context())