浏览代码

Kernel: Demangle userspace ELF symbols in backtraces

Turns out we can use abi::__cxa_demangle() for this, and all we need to
provide is sprintf(), realloc() and free(), so this patch exposes them.

We now have fully demangled C++ backtraces :^)
Andreas Kling 5 年之前
父节点
当前提交
0adbacf59e

+ 3 - 3
Kernel/FileSystem/ProcFS.cpp

@@ -502,7 +502,7 @@ Optional<KBuffer> procfs$pid_cwd(InodeIdentifier identifier)
 Optional<KBuffer> procfs$self(InodeIdentifier)
 {
     char buffer[16];
-    ksprintf(buffer, "%u", current->pid());
+    sprintf(buffer, "%u", current->pid());
     return KBuffer::copy((const u8*)buffer, strlen(buffer));
 }
 
@@ -1055,7 +1055,7 @@ bool ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)
         }
         for (auto pid_child : Process::all_pids()) {
             char name[16];
-            int name_length = ksprintf(name, "%u", pid_child);
+            int name_length = sprintf(name, "%u", pid_child);
             callback({ name, name_length, to_identifier(fsid(), PDI_Root, pid_child, FI_PID), 0 });
         }
         break;
@@ -1100,7 +1100,7 @@ bool ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)
             if (!description)
                 continue;
             char name[16];
-            int name_length = ksprintf(name, "%u", i);
+            int name_length = sprintf(name, "%u", i);
             callback({ name, name_length, to_identifier_with_fd(fsid(), pid, i), 0 });
         }
     } break;

+ 19 - 0
Kernel/Heap/kmalloc.cpp

@@ -184,6 +184,25 @@ void kfree(void* ptr)
 #endif
 }
 
+void* krealloc(void* ptr, size_t new_size)
+{
+    if (!ptr)
+        return kmalloc(new_size);
+
+    InterruptDisabler disabler;
+
+    auto* a = (allocation_t*)((((u8*)ptr) - sizeof(allocation_t)));
+    size_t old_size = a->nchunk * CHUNK_SIZE;
+
+    if (old_size == new_size)
+        return ptr;
+
+    auto* new_ptr = kmalloc(new_size);
+    memcpy(new_ptr, ptr, min(old_size, new_size));
+    kfree(ptr);
+    return new_ptr;
+}
+
 void* operator new(size_t size)
 {
     return kmalloc(size);

+ 1 - 0
Kernel/Heap/kmalloc.h

@@ -9,6 +9,7 @@ void kmalloc_init();
 [[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_eternal(size_t);
 [[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_page_aligned(size_t);
 [[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_aligned(size_t, size_t alignment);
+void* krealloc(void*, size_t);
 void kfree(void*);
 void kfree_aligned(void*);
 

+ 1 - 1
Kernel/Makefile

@@ -115,7 +115,7 @@ kernel.map: kernel
 	@echo "MKMAP $@"; sh mkmap.sh
 
 $(KERNEL): $(OBJS)
-	@echo "LD $@"; $(LD) $(LDFLAGS) -o $@ $(OBJS) -lgcc
+	@echo "LD $@"; $(LD) $(LDFLAGS) -o $@ $(OBJS) -lgcc -lstdc++
 
 .cpp.o:
 	@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<

+ 9 - 0
Kernel/StdLib.cpp

@@ -174,4 +174,13 @@ char* strstr(const char* haystack, const char* needle)
     ASSERT_NOT_REACHED();
 }
 
+void* realloc(void* p, size_t s)
+{
+    return krealloc(p, s);
+}
+
+void free(void* p)
+{
+    return kfree(p);
+}
 }

+ 1 - 1
Kernel/TTY/SlavePTY.cpp

@@ -10,7 +10,7 @@ SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
     , m_master(master)
     , m_index(index)
 {
-    ksprintf(m_tty_name, "/dev/pts/%u", m_index);
+    sprintf(m_tty_name, "/dev/pts/%u", m_index);
     set_uid(current->process().uid());
     set_gid(current->process().gid());
     DevPtsFS::register_slave_pty(*this);

+ 1 - 1
Kernel/TTY/VirtualConsole.cpp

@@ -41,7 +41,7 @@ VirtualConsole::VirtualConsole(unsigned index, InitialContents initial_contents)
     : TTY(4, index)
     , m_index(index)
 {
-    ksprintf(m_tty_name, "/dev/tty%u", m_index);
+    sprintf(m_tty_name, "/dev/tty%u", m_index);
     set_size(80, 25);
     m_horizontal_tabs = static_cast<u8*>(kmalloc_eternal(columns()));
     for (unsigned i = 0; i < columns(); ++i)

+ 1 - 1
Kernel/kprintf.cpp

@@ -96,7 +96,7 @@ static void buffer_putch(char*& bufptr, char ch)
     *bufptr++ = ch;
 }
 
-int ksprintf(char* buffer, const char* fmt, ...)
+int sprintf(char* buffer, const char* fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);

+ 1 - 1
Kernel/kstdio.h

@@ -6,7 +6,7 @@ extern "C" {
 int dbgprintf(const char* fmt, ...);
 int dbgputstr(const char*, int);
 int kprintf(const char* fmt, ...);
-int ksprintf(char* buf, const char* fmt, ...);
+int sprintf(char* buf, const char* fmt, ...);
 void set_serial_debug(bool on_or_off);
 int get_serial_debug();
 }

+ 7 - 1
Libraries/LibELF/ELFLoader.cpp

@@ -1,6 +1,7 @@
 #include "ELFLoader.h"
 #include <AK/QuickSort.h>
 #include <AK/kstdio.h>
+#include <cxxabi.h>
 
 #ifdef KERNEL
 #include <Kernel/VM/MemoryManager.h>
@@ -138,7 +139,12 @@ String ELFLoader::symbolicate(u32 address) const
             if (i == 0)
                 return "!!";
             auto& symbol = sorted_symbols[i - 1];
-            return String::format("%s +%u", symbol.name, address - symbol.address);
+            int status = 0;
+            auto* demangled_name = abi::__cxa_demangle(symbol.name, nullptr, nullptr, &status);
+            auto string = String::format("%s +%u", status == 0 ? demangled_name : symbol.name, address - symbol.address);
+            if (status == 0)
+                kfree(demangled_name);
+            return string;
         }
     }
     return "??";