소스 검색

Kernel: Separate out the symbol offsets in profile output

Instead of saying "main +39" and "main +57" etc, we now have a separate
field in /proc/profile for the offset-into-the-symbol.
Andreas Kling 5 년 전
부모
커밋
0f393148da
5개의 변경된 파일19개의 추가작업 그리고 8개의 파일을 삭제
  1. 1 0
      Kernel/FileSystem/ProcFS.cpp
  2. 11 6
      Kernel/Profiling.cpp
  3. 1 0
      Kernel/Profiling.h
  4. 5 1
      Libraries/LibELF/ELFLoader.cpp
  5. 1 1
      Libraries/LibELF/ELFLoader.h

+ 1 - 0
Kernel/FileSystem/ProcFS.cpp

@@ -372,6 +372,7 @@ Optional<KBuffer> procfs$profile(InodeIdentifier)
             auto frame_object = frames_array.add_object();
             frame_object.add("address", JsonValue((u32)sample.frames[i]));
             frame_object.add("symbol", sample.symbolicated_frames[i]);
+            frame_object.add("offset", JsonValue((u32)sample.offsets[i]));
             frame_object.finish();
         }
         frames_array.finish();

+ 11 - 6
Kernel/Profiling.cpp

@@ -57,19 +57,24 @@ static void symbolicate(Sample& stack)
     for (auto& symbol : recognized_symbols) {
         if (!symbol.address)
             break;
-        auto& symbol_string_slot = stack.symbolicated_frames[i++];
+        auto& symbol_string_slot = stack.symbolicated_frames[i];
+        auto& offset_slot = stack.offsets[i];
+        ++i;
         if (!symbol.ksym) {
             if (!Scheduler::is_active() && process.elf_loader() && process.elf_loader()->has_symbols())
-                symbol_string_slot = String::format("%s", process.elf_loader()->symbolicate(symbol.address).characters());
+                symbol_string_slot = process.elf_loader()->symbolicate(symbol.address, &offset_slot);
             else
                 symbol_string_slot = String::empty();
             continue;
         }
-        unsigned offset = symbol.address - symbol.ksym->address;
-        if (symbol.ksym->address == ksym_highest_address && offset > 4096)
+        u32 offset = symbol.address - symbol.ksym->address;
+        if (symbol.ksym->address == ksym_highest_address && offset > 4096) {
             symbol_string_slot = String::empty();
-        else
-            symbol_string_slot = String::format("%s +%u", demangle(symbol.ksym->name).characters(), offset);
+            offset_slot = 0;
+        } else {
+            symbol_string_slot = demangle(symbol.ksym->name);
+            offset_slot = offset;
+        }
     }
 }
 

+ 1 - 0
Kernel/Profiling.h

@@ -15,6 +15,7 @@ struct Sample {
     i32 tid;
     u64 timestamp;
     u32 frames[max_stack_frame_count];
+    u32 offsets[max_stack_frame_count];
     String symbolicated_frames[max_stack_frame_count];
 };
 

+ 5 - 1
Libraries/LibELF/ELFLoader.cpp

@@ -102,7 +102,7 @@ char* ELFLoader::symbol_ptr(const char* name)
     return found_ptr;
 }
 
-String ELFLoader::symbolicate(u32 address) const
+String ELFLoader::symbolicate(u32 address, u32* out_offset) const
 {
     SortedSymbol* sorted_symbols = nullptr;
 #ifdef KERNEL
@@ -139,6 +139,10 @@ String ELFLoader::symbolicate(u32 address) const
             if (i == 0)
                 return "!!";
             auto& symbol = sorted_symbols[i - 1];
+            if (out_offset) {
+                *out_offset = address - symbol.address;
+                return demangle(symbol.name);
+            }
             return String::format("%s +%u", demangle(symbol.name).characters(), address - symbol.address);
         }
     }

+ 1 - 1
Libraries/LibELF/ELFLoader.h

@@ -27,7 +27,7 @@ public:
 
     bool has_symbols() const { return m_image.symbol_count(); }
 
-    String symbolicate(u32 address) const;
+    String symbolicate(u32 address, u32* offset = nullptr) const;
 
 private:
     bool layout();