forked from OSchip/llvm-project
Add Debug Info Size to Symbol Status
If a module has debug info, the size of debug symbol will be displayed after the Symbols Loaded Message for each module in the VScode modules view.{F12335461} Reviewed By: wallace, clayborg Differential Revision: https://reviews.llvm.org/D83731
This commit is contained in:
parent
313b60742a
commit
2c1bea88a5
|
@ -53,11 +53,12 @@ class VSCodeTestCaseBase(TestBase):
|
|||
breakpoint_ids.append('%i' % (breakpoint['id']))
|
||||
return breakpoint_ids
|
||||
|
||||
def waitUntil(self, condition):
|
||||
while True:
|
||||
if condition():
|
||||
break
|
||||
def waitUntil(self, condition_callback):
|
||||
for _ in range(20):
|
||||
if condition_callback():
|
||||
return True
|
||||
time.sleep(0.5)
|
||||
return False
|
||||
|
||||
def verify_breakpoint_hit(self, breakpoint_ids):
|
||||
'''Wait for the process we are debugging to stop, and verify we hit
|
||||
|
|
|
@ -2,12 +2,16 @@ DYLIB_NAME := foo
|
|||
DYLIB_CXX_SOURCES := foo.cpp
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
all: a.out.stripped
|
||||
LD_EXTRAS := -Wl,-rpath "-Wl,$(shell pwd)"
|
||||
USE_LIBDL :=1
|
||||
|
||||
include Makefile.rules
|
||||
|
||||
a.out.stripped: a.out.dSYM
|
||||
all: a.out.stripped
|
||||
|
||||
a.out.stripped:
|
||||
strip -o a.out.stripped a.out
|
||||
|
||||
ifneq "$(CODESIGN)" ""
|
||||
$(CODESIGN) -fs - a.out.stripped
|
||||
endif
|
||||
endif
|
|
@ -10,56 +10,93 @@ from lldbsuite.test.decorators import *
|
|||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
import lldbvscode_testcase
|
||||
import re
|
||||
|
||||
class TestVSCode_module(lldbvscode_testcase.VSCodeTestCaseBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
|
||||
@skipIfWindows
|
||||
@skipUnlessDarwin
|
||||
@skipIfRemote
|
||||
def test_modules_event(self):
|
||||
def run_test(self, symbol_basename, expect_debug_info_size):
|
||||
program_basename = "a.out.stripped"
|
||||
program= self.getBuildArtifact(program_basename)
|
||||
program = self.getBuildArtifact(program_basename)
|
||||
self.build_and_launch(program)
|
||||
functions = ['foo']
|
||||
breakpoint_ids = self.set_function_breakpoints(functions)
|
||||
self.assertEquals(len(breakpoint_ids), len(functions),
|
||||
'expect one breakpoint')
|
||||
self.assertEquals(len(breakpoint_ids), len(functions), 'expect one breakpoint')
|
||||
self.continue_to_breakpoints(breakpoint_ids)
|
||||
active_modules = self.vscode.get_active_modules()
|
||||
self.assertIn(program_basename, active_modules, '%s module is in active modules' % (program_basename))
|
||||
program_module = active_modules[program_basename]
|
||||
self.assertIn(program_basename, active_modules, '%s module is in active modules' % (program_basename))
|
||||
self.assertIn('name', program_module, 'make sure name is in module')
|
||||
self.assertEqual(program_basename, program_module['name'])
|
||||
self.assertIn('path', program_module, 'make sure path is in module')
|
||||
self.assertEqual(program, program_module['path'])
|
||||
self.assertTrue('symbolFilePath' not in program_module, 'Make sure a.out.stripped has no debug info')
|
||||
self.assertEqual('Symbols not found.', program_module['symbolStatus'])
|
||||
symbol_path = self.getBuildArtifact("a.out")
|
||||
self.vscode.request_evaluate('`%s' % ('target symbols add -s "%s" "%s"' % (program, symbol_path)))
|
||||
symbols_path = self.getBuildArtifact(symbol_basename)
|
||||
self.vscode.request_evaluate('`%s' % ('target symbols add -s "%s" "%s"' % (program, symbols_path)))
|
||||
|
||||
def checkSymbolsLoaded():
|
||||
active_modules = self.vscode.get_active_modules()
|
||||
program_module = active_modules[program_basename]
|
||||
return 'Symbols loaded.' == program_module['symbolStatus']
|
||||
self.waitUntil(checkSymbolsLoaded)
|
||||
|
||||
def checkSymbolsLoadedWithSize():
|
||||
active_modules = self.vscode.get_active_modules()
|
||||
program_module = active_modules[program_basename]
|
||||
symbolsStatus = program_module['symbolStatus']
|
||||
symbol_regex = re.compile(r"Symbols loaded. \([0-9]+(\.[0-9]*)?[KMG]?B\)")
|
||||
return symbol_regex.match(program_module['symbolStatus'])
|
||||
|
||||
if expect_debug_info_size:
|
||||
self.waitUntil(checkSymbolsLoadedWithSize)
|
||||
else:
|
||||
self.waitUntil(checkSymbolsLoaded)
|
||||
active_modules = self.vscode.get_active_modules()
|
||||
program_module = active_modules[program_basename]
|
||||
self.assertEqual(program_basename, program_module['name'])
|
||||
self.assertEqual(program, program_module['path'])
|
||||
self.assertEqual('Symbols loaded.', program_module['symbolStatus'])
|
||||
self.assertIn('symbolFilePath', program_module)
|
||||
self.assertEqual(symbol_path, program_module['symbolFilePath'])
|
||||
self.assertIn(symbols_path, program_module['symbolFilePath'])
|
||||
self.assertIn('addressRange', program_module)
|
||||
|
||||
@skipIfWindows
|
||||
@skipUnlessDarwin
|
||||
@skipIfRemote
|
||||
#TODO: Update the Makefile so that this test runs on Linux
|
||||
def test_module_event(self):
|
||||
'''
|
||||
Mac or linux.
|
||||
|
||||
On mac, if we load a.out as our symbol file, we will use DWARF with .o files and we will
|
||||
have debug symbols, but we won't see any debug info size because all of the DWARF
|
||||
sections are in .o files.
|
||||
|
||||
On other platforms, we expect a.out to have debug info, so we will expect a size.
|
||||
expect_debug_info_size = platform.system() != 'Darwin'
|
||||
return self.run_test("a.out", expect_debug_info_size)
|
||||
'''
|
||||
expect_debug_info_size = platform.system() != 'Darwin'
|
||||
return self.run_test("a.out", expect_debug_info_size)
|
||||
|
||||
@skipIfWindows
|
||||
@skipUnlessDarwin
|
||||
@skipIfRemote
|
||||
def test_module_event_dsym(self):
|
||||
'''
|
||||
Darwin only test with dSYM file.
|
||||
|
||||
On mac, if we load a.out.dSYM as our symbol file, we will have debug symbols and we
|
||||
will have DWARF sections added to the module, so we will expect a size.
|
||||
return self.run_test("a.out.dSYM", True)
|
||||
'''
|
||||
return self.run_test("a.out.dSYM", True)
|
||||
|
||||
@skipIfWindows
|
||||
@skipUnlessDarwin
|
||||
@skipIfRemote
|
||||
def test_compile_units(self):
|
||||
program= self.getBuildArtifact("a.out")
|
||||
program = self.getBuildArtifact("a.out")
|
||||
self.build_and_launch(program)
|
||||
source = "main.cpp"
|
||||
main_source_path = self.getSourcePath(source)
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/FormatAdapters.h"
|
||||
|
@ -327,6 +329,50 @@ llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp,
|
|||
return llvm::json::Value(std::move(object));
|
||||
}
|
||||
|
||||
static uint64_t GetDebugInfoSizeInSection(lldb::SBSection section) {
|
||||
uint64_t debug_info_size = 0;
|
||||
llvm::StringRef section_name(section.GetName());
|
||||
if (section_name.startswith(".debug") || section_name.startswith("__debug") ||
|
||||
section_name.startswith(".apple") || section_name.startswith("__apple"))
|
||||
debug_info_size += section.GetFileByteSize();
|
||||
size_t num_sub_sections = section.GetNumSubSections();
|
||||
for (size_t i = 0; i < num_sub_sections; i++) {
|
||||
debug_info_size +=
|
||||
GetDebugInfoSizeInSection(section.GetSubSectionAtIndex(i));
|
||||
}
|
||||
return debug_info_size;
|
||||
}
|
||||
|
||||
static uint64_t GetDebugInfoSize(lldb::SBModule module) {
|
||||
uint64_t debug_info_size = 0;
|
||||
size_t num_sections = module.GetNumSections();
|
||||
for (size_t i = 0; i < num_sections; i++) {
|
||||
debug_info_size += GetDebugInfoSizeInSection(module.GetSectionAtIndex(i));
|
||||
}
|
||||
return debug_info_size;
|
||||
}
|
||||
|
||||
static std::string ConvertDebugInfoSizeToString(uint64_t debug_info) {
|
||||
std::ostringstream oss;
|
||||
oss << " (";
|
||||
oss << std::fixed << std::setprecision(1);
|
||||
|
||||
if (debug_info < 1024) {
|
||||
oss << debug_info << "B";
|
||||
} else if (debug_info < 1024 * 1024) {
|
||||
double kb = double(debug_info) / 1024.0;
|
||||
oss << kb << "KB";
|
||||
} else if (debug_info < 1024 * 1024 * 1024) {
|
||||
double mb = double(debug_info) / (1024.0 * 1024.0);
|
||||
oss << mb << "MB";
|
||||
} else {
|
||||
double gb = double(debug_info) / (1024.0 * 1024.0 * 1024.0);
|
||||
oss << gb << "GB";
|
||||
;
|
||||
}
|
||||
oss << ")";
|
||||
return oss.str();
|
||||
}
|
||||
llvm::json::Value CreateModule(lldb::SBModule &module) {
|
||||
llvm::json::Object object;
|
||||
if (!module.IsValid())
|
||||
|
@ -339,9 +385,15 @@ llvm::json::Value CreateModule(lldb::SBModule &module) {
|
|||
std::string module_path(module_path_arr);
|
||||
object.try_emplace("path", module_path);
|
||||
if (module.GetNumCompileUnits() > 0) {
|
||||
object.try_emplace("symbolStatus", "Symbols loaded.");
|
||||
std::string symbol_str = "Symbols loaded.";
|
||||
uint64_t debug_info = GetDebugInfoSize(module);
|
||||
if (debug_info > 0) {
|
||||
symbol_str += ConvertDebugInfoSizeToString(debug_info);
|
||||
}
|
||||
object.try_emplace("symbolStatus", symbol_str);
|
||||
char symbol_path_arr[PATH_MAX];
|
||||
module.GetSymbolFileSpec().GetPath(symbol_path_arr, sizeof(symbol_path_arr));
|
||||
module.GetSymbolFileSpec().GetPath(symbol_path_arr,
|
||||
sizeof(symbol_path_arr));
|
||||
std::string symbol_path(symbol_path_arr);
|
||||
object.try_emplace("symbolFilePath", symbol_path);
|
||||
} else {
|
||||
|
@ -352,8 +404,9 @@ llvm::json::Value CreateModule(lldb::SBModule &module) {
|
|||
object.try_emplace("addressRange", loaded_addr);
|
||||
std::string version_str;
|
||||
uint32_t version_nums[3];
|
||||
uint32_t num_versions = module.GetVersion(version_nums, sizeof(version_nums)/sizeof(uint32_t));
|
||||
for (uint32_t i=0; i<num_versions; ++i) {
|
||||
uint32_t num_versions =
|
||||
module.GetVersion(version_nums, sizeof(version_nums) / sizeof(uint32_t));
|
||||
for (uint32_t i = 0; i < num_versions; ++i) {
|
||||
if (!version_str.empty())
|
||||
version_str += ".";
|
||||
version_str += std::to_string(version_nums[i]);
|
||||
|
|
Loading…
Reference in New Issue