This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 6dea4d41bae0b401396cc5297fd0c87ad0152c82
Author: liang.huang <[email protected]>
AuthorDate: Sat Jul 25 13:30:13 2026 +0800

    libs/libc/symtab: fix bogus symbol size under SYMTAB_ORDEREDBYNAME
    
    allsyms_lookup() derived a symbol's size from the physically next table
    entry, assuming address order. Under CONFIG_SYMTAB_ORDEREDBYNAME the
    table is sorted by name instead, producing a huge bogus size in
    %pS/backtrace output.
    
    Scan for the closest larger address instead of relying on table order.
    
    Signed-off-by: liang.huang <[email protected]>
    Assisted-by: Claude Code:claude-sonnet-5
---
 libs/libc/symtab/symtab_allsyms.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/libs/libc/symtab/symtab_allsyms.c 
b/libs/libc/symtab/symtab_allsyms.c
index 7e66533bf63..5cd856929f3 100644
--- a/libs/libc/symtab/symtab_allsyms.c
+++ b/libs/libc/symtab/symtab_allsyms.c
@@ -75,7 +75,38 @@ allsyms_lookup(FAR const char *name, FAR void *value,
         }
     }
 
-  if (symbol && symbol != &g_allsyms[g_nallsyms - 1])
+  if (symbol == NULL)
+    {
+      *size = 0;
+      return NULL;
+    }
+
+#ifdef CONFIG_SYMTAB_ORDEREDBYNAME
+  /* g_allsyms is sorted by name here, not by value, so the physically
+   * next table entry is not necessarily the next symbol by address.
+   * Scan the real symbols (index 1..g_nallsyms - 2; 0 and g_nallsyms - 1
+   * are the boundary sentinels) for the smallest address greater than
+   * this symbol's, falling back to the high sentinel's now-meaningful
+   * value if none is closer.
+   */
+
+  {
+    FAR const struct symtab_s *next = &g_allsyms[g_nallsyms - 1];
+    int i;
+
+    for (i = 1; i < g_nallsyms - 1; i++)
+      {
+        if (g_allsyms[i].sym_value > symbol->sym_value &&
+            g_allsyms[i].sym_value < next->sym_value)
+          {
+            next = &g_allsyms[i];
+          }
+      }
+
+    *size = next->sym_value - symbol->sym_value;
+  }
+#else
+  if (symbol != &g_allsyms[g_nallsyms - 1])
     {
       *size = (symbol + 1)->sym_value - symbol->sym_value;
     }
@@ -83,6 +114,7 @@ allsyms_lookup(FAR const char *name, FAR void *value,
     {
       *size = 0;
     }
+#endif
 
   return symbol;
 }

Reply via email to