[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, asmith, labath. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor, mgorny. This patch introduces the simple `PDBNameParser`. It is needed for parsing names of PDB symbols corresponding to template instantiations. For example, for the name `N0::N1::Template` we can't just split the name with `::` (as it is implemented for now) to retrieve its scopes. This parser processes such names in a more correct way. Repository: rLLDB LLDB https://reviews.llvm.org/D52461 Files: lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp lit/SymbolFile/PDB/ast-restore.test source/Plugins/SymbolFile/PDB/CMakeLists.txt source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.h source/Plugins/SymbolFile/PDB/PDBNameParser.cpp source/Plugins/SymbolFile/PDB/PDBNameParser.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -9,6 +9,10 @@ #include "SymbolFilePDB.h" +#include "PDBASTParser.h" +#include "PDBLocationToDWARFExpression.h" +#include "PDBNameParser.h" + #include "clang/Lex/Lexer.h" #include "lldb/Core/Module.h" @@ -46,8 +50,6 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName -#include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" #include @@ -1058,7 +1060,7 @@ continue; if (!name.GetStringRef().equals( -PDBASTParser::PDBNameDropScope(pdb_data->getName( +PDBNameParser::DropScope(pdb_data->getName( continue; auto actual_parent_decl_ctx = @@ -1166,16 +1168,7 @@ // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does // not have inforamtion of this, we extract base names and cache them // by our own effort. -llvm::StringRef basename; -CPlusPlusLanguage::MethodName cpp_method(cstr_name); -if (cpp_method.IsValid()) { - llvm::StringRef context; - basename = cpp_method.GetBasename(); - if (basename.empty()) -CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), - context, basename); -} - +auto basename = PDBNameParser::DropScope(name); if (!basename.empty()) m_func_base_names.Append(ConstString(basename), uid); else { @@ -1188,11 +1181,12 @@ } else { // Handle not-method symbols. -// The function name might contain namespace, or its lexical scope. It -// is not safe to get its base name by applying same scheme as we deal -// with the method names. -// FIXME: Remove namespace if function is static in a scope. -m_func_base_names.Append(ConstString(name), uid); +// The function name might contain namespace, or its lexical scope. +auto basename = PDBNameParser::DropScope(name); +if (!basename.empty()) + m_func_base_names.Append(ConstString(basename), uid); +else + m_func_base_names.Append(ConstString(name), uid); if (name == "main") { m_func_full_names.Append(ConstString(name), uid); @@ -1420,8 +1414,7 @@ if (max_matches > 0 && matches >= max_matches) break; -if (PDBASTParser::PDBNameDropScope(result->getRawSymbol().getName()) != -name) +if (PDBNameParser::DropScope(result->getRawSymbol().getName()) != name) continue; switch (result->getSymTag()) { Index: source/Plugins/SymbolFile/PDB/PDBNameParser.h === --- /dev/null +++ source/Plugins/SymbolFile/PDB/PDBNameParser.h @@ -0,0 +1,47 @@ +//===-- PDBNameParser.h -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#ifndef LLDB_PLUGINS_SYMBOLFILE_PDB_PDBNAMEPARSER_H +#define LLDB_PLUGINS_SYMBOLFILE_PDB_PDBNAMEPARSER_H + +#include + +#include "llvm/ADT/StringRef.h" + +class PDBNameSpecifier { +public: + PDBNameSpecifier(llvm::StringRef full_name, llvm::StringRef base_name) + : m_full_name(full_name), m_base_name(base_name) {} + + llvm::StringRef GetFullName() const { return m_full_name; } + llvm::StringRef GetBaseName() const { return m_base_name; } + +private: + llvm::StringRef m_full_name; + llvm::StringRef m_base_name; +}; + +class PDBNameParser { +pub
[Lldb-commits] [PATCH] D52468: [PDB] Treat `char`, `signed char` and `unsigned char` as three different types
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: asmith, zturner, labath. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor. `char`, `signed char` and `unsigned char` are three different types, and they are mangled differently: void __declspec(dllexport) /* ?foo@@YAXD@Z */ foo(char c) { } void __declspec(dllexport) /* ?foo@@YAXE@Z */ foo(unsigned char c) { } void __declspec(dllexport) /* ?foo@@YAXC@Z */ foo(signed char c) { } Repository: rLLDB LLDB https://reviews.llvm.org/D52468 Files: lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp lit/SymbolFile/PDB/ast-restore.test lit/SymbolFile/PDB/func-symbols.test lit/SymbolFile/PDB/typedefs.test source/Plugins/SymbolFile/PDB/PDBASTParser.cpp Index: source/Plugins/SymbolFile/PDB/PDBASTParser.cpp === --- source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -113,6 +113,8 @@ return CompilerType(); case PDB_BuiltinType::Void: return clang_ast.GetBasicType(eBasicTypeVoid); + case PDB_BuiltinType::Char: +return clang_ast.GetBasicType(eBasicTypeChar); case PDB_BuiltinType::Bool: return clang_ast.GetBasicType(eBasicTypeBool); case PDB_BuiltinType::Long: Index: lit/SymbolFile/PDB/typedefs.test === --- lit/SymbolFile/PDB/typedefs.test +++ lit/SymbolFile/PDB/typedefs.test @@ -46,9 +46,10 @@ CHECK-DAG: Type{{.*}} , name = "long", size = 4, compiler_type = {{.*}} long CHECK-DAG: Type{{.*}} , name = "unsigned short", size = 2, compiler_type = {{.*}} unsigned short CHECK-DAG: Type{{.*}} , name = "unsigned int", size = 4, compiler_type = {{.*}} unsigned int +CHECK-DAG: Type{{.*}} , name = "char", size = 1, compiler_type = {{.*}} char CHECK-DAG: Type{{.*}} , name = "signed char", size = 1, compiler_type = {{.*}} signed char -CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} signed char (void *, long, unsigned short, unsigned int, ...) -CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} signed char (*)(void *, long, unsigned short, unsigned int, ...) +CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} char (void *, long, unsigned short, unsigned int, ...) +CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} char (*)(void *, long, unsigned short, unsigned int, ...) CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedef", compiler_type = {{.*}} typedef VarArgsFuncTypedef CHECK-DAG: Type{{.*}} , name = "float", size = 4, compiler_type = {{.*}} float Index: lit/SymbolFile/PDB/func-symbols.test === --- lit/SymbolFile/PDB/func-symbols.test +++ lit/SymbolFile/PDB/func-symbols.test @@ -14,7 +14,7 @@ CHECK-ONE-DAG: [[TY1:.*]]: Type{[[UID1:.*]]} , name = "Func_arg_void", decl = FuncSymbolsTestMain.cpp:4, compiler_type = {{.*}} void (void) CHECK-ONE-DAG: [[TY2:.*]]: Type{[[UID2:.*]]} , name = "Func_arg_none", decl = FuncSymbolsTestMain.cpp:5, compiler_type = {{.*}} void (void) CHECK-ONE-DAG: [[TY3:.*]]: Type{[[UID3:.*]]} , name = "Func_varargs", decl = FuncSymbolsTestMain.cpp:6, compiler_type = {{.*}} void (...) -CHECK-ONE-DAG: [[TY4:.*]]: Type{[[UID4:.*]]} , name = "Func", decl = FuncSymbolsTestMain.cpp:28, compiler_type = {{.*}} void (signed char, int) +CHECK-ONE-DAG: [[TY4:.*]]: Type{[[UID4:.*]]} , name = "Func", decl = FuncSymbolsTestMain.cpp:28, compiler_type = {{.*}} void (char, int) CHECK-ONE-DAG: [[TY5:.*]]: Type{[[UID5:.*]]} , name = "main", decl = FuncSymbolsTestMain.cpp:44, compiler_type = {{.*}} int (void) CHECK-ONE-DAG: [[TY6:.*]]: Type{[[UID6:.*]]} , name = "Func", decl = FuncSymbolsTestMain.cpp:24, compiler_type = {{.*}} void (int, const long, volatile _Bool, ...) CHECK-ONE-DAG: [[TY7:.*]]: Type{[[UID7:.*]]} , name = "StaticFunction", decl = FuncSymbolsTestMain.cpp:35, compiler_type = {{.*}} long (int) Index: lit/SymbolFile/PDB/ast-restore.test === --- lit/SymbolFile/PDB/ast-restore.test +++ lit/SymbolFile/PDB/ast-restore.test @@ -58,7 +58,7 @@ INNER: namespace N1 { INNER: class Class : public N0::N1::Base { INNER: struct Inner { -INNER: signed char x; +INNER: char x; INNER: short y; INNER: int z; INNER: }; Index: lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp === --- lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp +++ lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp @@ -35,6 +35,9 @@ enum struct EnumStruct { red, blue, black }; EnumStruct EnumStructVar; +typedef signed char SCharTypedef; +SCharTypedef SCVar; + typedef char16_t WChar16Typedef; WChar16Typedef WC16Var; Index: source/Plugins/SymbolFile/PDB/PDBASTParser.cpp ==
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a comment. Ok, I'll look into that, thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52501: [PDB] Restore the calling convention from PDB
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: clayborg, zturner, labath, asmith. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor. This patch implements restoring of the calling convention from PDB. It is necessary for expressions evaluation, if we want to call a function of the debuggee process with a calling convention other than ccall. Repository: rLLDB LLDB https://reviews.llvm.org/D52501 Files: include/lldb/Symbol/ClangASTContext.h lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp lit/SymbolFile/PDB/ast-restore.test lit/SymbolFile/PDB/pointers.test source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Symbol/ClangASTContext.cpp Index: source/Symbol/ClangASTContext.cpp === --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -2058,7 +2058,8 @@ CompilerType ClangASTContext::CreateFunctionType( ASTContext *ast, const CompilerType &result_type, const CompilerType *args, -unsigned num_args, bool is_variadic, unsigned type_quals) { +unsigned num_args, bool is_variadic, unsigned type_quals, +clang::CallingConv cc) { if (ast == nullptr) return CompilerType(); // invalid AST @@ -2086,6 +2087,7 @@ // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; + proto_info.ExtInfo = cc; proto_info.Variadic = is_variadic; proto_info.ExceptionSpec = EST_None; proto_info.TypeQuals = type_quals; Index: source/Plugins/SymbolFile/PDB/PDBASTParser.cpp === --- source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -331,6 +331,26 @@ return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; } +static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { + switch (pdb_cc) { + case llvm::codeview::CallingConvention::NearC: +return clang::CC_C; + case llvm::codeview::CallingConvention::NearStdCall: +return clang::CC_X86StdCall; + case llvm::codeview::CallingConvention::NearFast: +return clang::CC_X86FastCall; + case llvm::codeview::CallingConvention::ThisCall: +return clang::CC_X86ThisCall; + case llvm::codeview::CallingConvention::NearVector: +return clang::CC_X86VectorCall; + case llvm::codeview::CallingConvention::NearPascal: +return clang::CC_X86Pascal; + default: +assert(false && "Unknown calling convention"); +return clang::CC_C; + } +} + PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} PDBASTParser::~PDBASTParser() {} @@ -603,9 +623,10 @@ type_quals |= clang::Qualifiers::Const; if (func_sig->isVolatileType()) type_quals |= clang::Qualifiers::Volatile; +auto cc = TranslateCallingConvention(func_sig->getCallingConvention()); CompilerType func_sig_ast_type = m_ast.CreateFunctionType(return_ast_type, arg_list.data(), - arg_list.size(), is_variadic, type_quals); + arg_list.size(), is_variadic, type_quals, cc); GetDeclarationForSymbol(type, decl); return std::make_shared( Index: lit/SymbolFile/PDB/pointers.test === --- lit/SymbolFile/PDB/pointers.test +++ lit/SymbolFile/PDB/pointers.test @@ -28,7 +28,7 @@ MAIN: Variable{{.*}}, name = "p_member_field" MAIN-SAME:(int ST::*), scope = local MAIN: Variable{{.*}}, name = "p_member_method" -MAIN-SAME:(int (ST::*)(int)), scope = local +MAIN-SAME:(int (ST::*)(int) __attribute__((thiscall))), scope = local F: Function{[[FID2:.*]]}, demangled = {{.*}}f(int) F-NEXT: Block{[[FID2]]} Index: lit/SymbolFile/PDB/ast-restore.test === --- lit/SymbolFile/PDB/ast-restore.test +++ lit/SymbolFile/PDB/ast-restore.test @@ -7,6 +7,7 @@ RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CLASS %s RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=INNER %s RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=FOO %s +RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CC %s RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=MAIN %s ENUM: Module: {{.*}} @@ -73,5 +74,10 @@ FOO: } FOO: } +CC: Module: {{.*}} +CC-DAG: int (*FuncStdCallPtr)() __attribute__((stdcall)); +CC-DAG: int (*FuncFastCallPtr)() __attribute__((fastcall)); +CC-DAG: int (*FuncVectorCallPtr)() __attribute__((vectorcall)); + MAIN: Module: {{.*}} MAIN: int main(); Index: lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp === --- lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp +++ lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp @@ -41,6 +41,13 @@ } // namespace N1
[Lldb-commits] [PATCH] D52501: [PDB] Restore the calling convention from PDB
aleksandr.urakov updated this revision to Diff 167081. aleksandr.urakov added a comment. Thanks! I just have extracted the test cases in a separate test and have specified `-m32` key, so the test can run also on 64-bit machines. https://reviews.llvm.org/D52501 Files: include/lldb/Symbol/ClangASTContext.h lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp lit/SymbolFile/PDB/calling-conventions.test lit/SymbolFile/PDB/pointers.test source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Symbol/ClangASTContext.cpp Index: source/Symbol/ClangASTContext.cpp === --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -2058,7 +2058,8 @@ CompilerType ClangASTContext::CreateFunctionType( ASTContext *ast, const CompilerType &result_type, const CompilerType *args, -unsigned num_args, bool is_variadic, unsigned type_quals) { +unsigned num_args, bool is_variadic, unsigned type_quals, +clang::CallingConv cc) { if (ast == nullptr) return CompilerType(); // invalid AST @@ -2086,6 +2087,7 @@ // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; + proto_info.ExtInfo = cc; proto_info.Variadic = is_variadic; proto_info.ExceptionSpec = EST_None; proto_info.TypeQuals = type_quals; Index: source/Plugins/SymbolFile/PDB/PDBASTParser.cpp === --- source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -331,6 +331,26 @@ return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; } +static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { + switch (pdb_cc) { + case llvm::codeview::CallingConvention::NearC: +return clang::CC_C; + case llvm::codeview::CallingConvention::NearStdCall: +return clang::CC_X86StdCall; + case llvm::codeview::CallingConvention::NearFast: +return clang::CC_X86FastCall; + case llvm::codeview::CallingConvention::ThisCall: +return clang::CC_X86ThisCall; + case llvm::codeview::CallingConvention::NearVector: +return clang::CC_X86VectorCall; + case llvm::codeview::CallingConvention::NearPascal: +return clang::CC_X86Pascal; + default: +assert(false && "Unknown calling convention"); +return clang::CC_C; + } +} + PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} PDBASTParser::~PDBASTParser() {} @@ -603,9 +623,10 @@ type_quals |= clang::Qualifiers::Const; if (func_sig->isVolatileType()) type_quals |= clang::Qualifiers::Volatile; +auto cc = TranslateCallingConvention(func_sig->getCallingConvention()); CompilerType func_sig_ast_type = m_ast.CreateFunctionType(return_ast_type, arg_list.data(), - arg_list.size(), is_variadic, type_quals); + arg_list.size(), is_variadic, type_quals, cc); GetDeclarationForSymbol(type, decl); return std::make_shared( Index: lit/SymbolFile/PDB/pointers.test === --- lit/SymbolFile/PDB/pointers.test +++ lit/SymbolFile/PDB/pointers.test @@ -28,7 +28,7 @@ MAIN: Variable{{.*}}, name = "p_member_field" MAIN-SAME:(int ST::*), scope = local MAIN: Variable{{.*}}, name = "p_member_method" -MAIN-SAME:(int (ST::*)(int)), scope = local +MAIN-SAME:(int (ST::*)(int) __attribute__((thiscall))), scope = local F: Function{[[FID2:.*]]}, demangled = {{.*}}f(int) F-NEXT: Block{[[FID2]]} Index: lit/SymbolFile/PDB/calling-conventions.test === --- /dev/null +++ lit/SymbolFile/PDB/calling-conventions.test @@ -0,0 +1,11 @@ +REQUIRES: windows, lld +RUN: clang-cl -m32 /Zi /GS- /c %S/Inputs/CallingConventionsTest.cpp /o %t.obj +RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe +RUN: lldb-test symbols -dump-ast %t.exe | FileCheck %s + +CHECK: Module: {{.*}} +CHECK-DAG: int (*FuncCCallPtr)(); +CHECK-DAG: int (*FuncStdCallPtr)() __attribute__((stdcall)); +CHECK-DAG: int (*FuncFastCallPtr)() __attribute__((fastcall)); +CHECK-DAG: int (*FuncVectorCallPtr)() __attribute__((vectorcall)); +CHECK-DAG: int (S::*FuncThisCallPtr)() __attribute__((thiscall)); Index: lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp === --- /dev/null +++ lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp @@ -0,0 +1,20 @@ +int FuncCCall() { return 0; } +auto FuncCCallPtr = &FuncCCall; + +int __stdcall FuncStdCall() { return 0; } +auto FuncStdCallPtr = &FuncStdCall; + +int __fastcall FuncFastCall() { return 0; } +auto FuncFastCallPtr = &FuncFastCall; + +int __vectorcall FuncVectorCall() { return 0; } +auto FuncVectorCallPtr = &FuncVectorCall; + +struct S { + int FuncThisCall() { return 0; } +}; +
[Lldb-commits] [PATCH] D52501: [PDB] Restore the calling convention from PDB
This revision was automatically updated to reflect the committed changes. Closed by commit rL343084: [PDB] Restore the calling convention from PDB (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D52501?vs=167081&id=167084#toc Repository: rL LLVM https://reviews.llvm.org/D52501 Files: lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp lldb/trunk/lit/SymbolFile/PDB/calling-conventions.test lldb/trunk/lit/SymbolFile/PDB/pointers.test lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Index: lldb/trunk/source/Symbol/ClangASTContext.cpp === --- lldb/trunk/source/Symbol/ClangASTContext.cpp +++ lldb/trunk/source/Symbol/ClangASTContext.cpp @@ -2058,7 +2058,8 @@ CompilerType ClangASTContext::CreateFunctionType( ASTContext *ast, const CompilerType &result_type, const CompilerType *args, -unsigned num_args, bool is_variadic, unsigned type_quals) { +unsigned num_args, bool is_variadic, unsigned type_quals, +clang::CallingConv cc) { if (ast == nullptr) return CompilerType(); // invalid AST @@ -2086,6 +2087,7 @@ // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; + proto_info.ExtInfo = cc; proto_info.Variadic = is_variadic; proto_info.ExceptionSpec = EST_None; proto_info.TypeQuals = type_quals; Index: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp === --- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -331,6 +331,26 @@ return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; } +static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { + switch (pdb_cc) { + case llvm::codeview::CallingConvention::NearC: +return clang::CC_C; + case llvm::codeview::CallingConvention::NearStdCall: +return clang::CC_X86StdCall; + case llvm::codeview::CallingConvention::NearFast: +return clang::CC_X86FastCall; + case llvm::codeview::CallingConvention::ThisCall: +return clang::CC_X86ThisCall; + case llvm::codeview::CallingConvention::NearVector: +return clang::CC_X86VectorCall; + case llvm::codeview::CallingConvention::NearPascal: +return clang::CC_X86Pascal; + default: +assert(false && "Unknown calling convention"); +return clang::CC_C; + } +} + PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} PDBASTParser::~PDBASTParser() {} @@ -603,9 +623,10 @@ type_quals |= clang::Qualifiers::Const; if (func_sig->isVolatileType()) type_quals |= clang::Qualifiers::Volatile; +auto cc = TranslateCallingConvention(func_sig->getCallingConvention()); CompilerType func_sig_ast_type = m_ast.CreateFunctionType(return_ast_type, arg_list.data(), - arg_list.size(), is_variadic, type_quals); + arg_list.size(), is_variadic, type_quals, cc); GetDeclarationForSymbol(type, decl); return std::make_shared( Index: lldb/trunk/lit/SymbolFile/PDB/calling-conventions.test === --- lldb/trunk/lit/SymbolFile/PDB/calling-conventions.test +++ lldb/trunk/lit/SymbolFile/PDB/calling-conventions.test @@ -0,0 +1,11 @@ +REQUIRES: windows, lld +RUN: clang-cl -m32 /Zi /GS- /c %S/Inputs/CallingConventionsTest.cpp /o %t.obj +RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe +RUN: lldb-test symbols -dump-ast %t.exe | FileCheck %s + +CHECK: Module: {{.*}} +CHECK-DAG: int (*FuncCCallPtr)(); +CHECK-DAG: int (*FuncStdCallPtr)() __attribute__((stdcall)); +CHECK-DAG: int (*FuncFastCallPtr)() __attribute__((fastcall)); +CHECK-DAG: int (*FuncVectorCallPtr)() __attribute__((vectorcall)); +CHECK-DAG: int (S::*FuncThisCallPtr)() __attribute__((thiscall)); Index: lldb/trunk/lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp === --- lldb/trunk/lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp +++ lldb/trunk/lit/SymbolFile/PDB/Inputs/CallingConventionsTest.cpp @@ -0,0 +1,20 @@ +int FuncCCall() { return 0; } +auto FuncCCallPtr = &FuncCCall; + +int __stdcall FuncStdCall() { return 0; } +auto FuncStdCallPtr = &FuncStdCall; + +int __fastcall FuncFastCall() { return 0; } +auto FuncFastCallPtr = &FuncFastCall; + +int __vectorcall FuncVectorCall() { return 0; } +auto FuncVectorCallPtr = &FuncVectorCall; + +struct S { + int FuncThisCall() { return 0; } +}; +auto FuncThisCallPtr = &S::FuncThisCall; + +int main() { + return 0; +} Index: lldb/trunk/lit/SymbolFile/PDB/pointers.test ==
[Lldb-commits] [PATCH] D52618: [Windows] A basic implementation of memory allocations in a debuggee process
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, asmith, stella.stamenova, labath. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor, abidh. This patch adds a basic implementation of `DoAllocateMemory` and `DoDeallocateMemory` for Windows processes. For now it considers only the executable permission (and always allows reads and writes). To run tests on x86 it requires https://reviews.llvm.org/D52613 Repository: rLLDB LLDB https://reviews.llvm.org/D52618 Files: lit/Expr/TestIRMemoryMap.test lit/Expr/TestIRMemoryMapWindows.test source/Plugins/Process/Windows/Common/ProcessWindows.cpp source/Plugins/Process/Windows/Common/ProcessWindows.h Index: source/Plugins/Process/Windows/Common/ProcessWindows.h === --- source/Plugins/Process/Windows/Common/ProcessWindows.h +++ source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -84,6 +84,8 @@ Status &error) override; size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override; + lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override; + Status DoDeallocateMemory(lldb::addr_t ptr) override; Status GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override; Index: source/Plugins/Process/Windows/Common/ProcessWindows.cpp === --- source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -72,6 +72,20 @@ return file_name; } +DWORD ConvertLldbToWinApiProtect(uint32_t protect) { + // We also can process a read / write permissions here, but if the debugger + // will make later a write into the allocated memory, it will fail. To get + // around it is possible inside DoWriteMemory to remember memory permissions, + // allow write, write and restore permissions, but for now we process only + // the executable permission. + // + // TODO: Process permissions other than executable + if (protect & ePermissionsExecutable) +return PAGE_EXECUTE_READWRITE; + + return PAGE_READWRITE; +} + } // anonymous namespace namespace lldb_private { @@ -695,6 +709,54 @@ return bytes_written; } +lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, Status& error) { + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size, permissions); + + if (!m_session_data) { +LLDB_LOG(log, "cannot allocate, there is no active debugger connection."); +error.SetErrorString("cannot allocate, there is no active debugger connection"); +return 0; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + auto protect = ConvertLldbToWinApiProtect(permissions); + auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect); + if (!result) { +error.SetError(GetLastError(), eErrorTypeWin32); +LLDB_LOG(log, "allocating failed with error: {0}", error); +return 0; + } + + return reinterpret_cast(result); +} + +Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) { + Status result; + + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr); + + if (!m_session_data) { +LLDB_LOG(log, "cannot deallocate, there is no active debugger connection."); +result.SetErrorString("cannot deallocate, there is no active debugger connection"); +return result; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + if (!VirtualFreeEx(handle, reinterpret_cast(ptr), 0, MEM_RELEASE)) { +result.SetError(GetLastError(), eErrorTypeWin32); +LLDB_LOG(log, "deallocating failed with error: {0}", result); +return result; + } + + return result; +} + Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); Index: lit/Expr/TestIRMemoryMapWindows.test === --- /dev/null +++ lit/Expr/TestIRMemoryMapWindows.test @@ -0,0 +1,12 @@ +# REQUIRES: windows + +# RUN: clang-cl /Zi %p/Inputs/call-function.cpp -o %t + +# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-basic +# RUN: lldb-test ir-memory-map -host-only %t %S/Inputs/ir-memory-map-basic + +# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-overlap1 +# RUN: lldb-test ir-memory-map -host
[Lldb-commits] [PATCH] D52618: [Windows] A basic implementation of memory allocations in a debuggee process
aleksandr.urakov updated this revision to Diff 167338. aleksandr.urakov added a comment. Clang-format patch. https://reviews.llvm.org/D52618 Files: lit/Expr/TestIRMemoryMap.test lit/Expr/TestIRMemoryMapWindows.test source/Plugins/Process/Windows/Common/ProcessWindows.cpp source/Plugins/Process/Windows/Common/ProcessWindows.h Index: source/Plugins/Process/Windows/Common/ProcessWindows.h === --- source/Plugins/Process/Windows/Common/ProcessWindows.h +++ source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -84,6 +84,9 @@ Status &error) override; size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override; + lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, +Status &error) override; + Status DoDeallocateMemory(lldb::addr_t ptr) override; Status GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override; Index: source/Plugins/Process/Windows/Common/ProcessWindows.cpp === --- source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -72,6 +72,20 @@ return file_name; } +DWORD ConvertLldbToWinApiProtect(uint32_t protect) { + // We also can process a read / write permissions here, but if the debugger + // will make later a write into the allocated memory, it will fail. To get + // around it is possible inside DoWriteMemory to remember memory permissions, + // allow write, write and restore permissions, but for now we process only + // the executable permission. + // + // TODO: Process permissions other than executable + if (protect & ePermissionsExecutable) +return PAGE_EXECUTE_READWRITE; + + return PAGE_READWRITE; +} + } // anonymous namespace namespace lldb_private { @@ -695,6 +709,58 @@ return bytes_written; } +lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) { + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size, + permissions); + + if (!m_session_data) { +LLDB_LOG(log, "cannot allocate, there is no active debugger connection."); +error.SetErrorString( +"cannot allocate, there is no active debugger connection"); +return 0; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + auto protect = ConvertLldbToWinApiProtect(permissions); + auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect); + if (!result) { +error.SetError(GetLastError(), eErrorTypeWin32); +LLDB_LOG(log, "allocating failed with error: {0}", error); +return 0; + } + + return reinterpret_cast(result); +} + +Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) { + Status result; + + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr); + + if (!m_session_data) { +LLDB_LOG(log, "cannot deallocate, there is no active debugger connection."); +result.SetErrorString( +"cannot deallocate, there is no active debugger connection"); +return result; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + if (!VirtualFreeEx(handle, reinterpret_cast(ptr), 0, MEM_RELEASE)) { +result.SetError(GetLastError(), eErrorTypeWin32); +LLDB_LOG(log, "deallocating failed with error: {0}", result); +return result; + } + + return result; +} + Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); Index: lit/Expr/TestIRMemoryMapWindows.test === --- /dev/null +++ lit/Expr/TestIRMemoryMapWindows.test @@ -0,0 +1,12 @@ +# REQUIRES: windows + +# RUN: clang-cl /Zi %p/Inputs/call-function.cpp -o %t + +# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-basic +# RUN: lldb-test ir-memory-map -host-only %t %S/Inputs/ir-memory-map-basic + +# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-overlap1 +# RUN: lldb-test ir-memory-map -host-only %t %S/Inputs/ir-memory-map-overlap1 + +# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-mix-malloc-free +# RUN: lldb-test ir-memory-map -host-only %t %S/Inputs/ir-memory-map-mix-malloc-free Index: lit/Expr/TestIRMemoryMap.test
[Lldb-commits] [PATCH] D52618: [Windows] A basic implementation of memory allocations in a debuggee process
aleksandr.urakov added a comment. I didn't know about such a priority, thanks... But in this case `lldb-server` also must be able to allocate, read and write in a debuggee. Doesn't it use the process plugin for that? Or somehow duplicates this functionality? I have made some work on expressions evaluation on Windows, and it requires a possibility to allocate memory in a debuggee. Now I understand, that the priority is `lldb-server`, but is it a bad idea to apply now the changes I've made to proceed with expressions? I can look tomorrow what else was made with the process plugin, but it seems that there are not so many changes. Don't you know about the status of `lldb-server` on Windows? How much work requires it? https://reviews.llvm.org/D52618 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52468: [PDB] Treat `char`, `signed char` and `unsigned char` as three different types
aleksandr.urakov added a comment. Yes, sure! Thanks all! Repository: rLLDB LLDB https://reviews.llvm.org/D52468 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52468: [PDB] Treat `char`, `signed char` and `unsigned char` as three different types
This revision was automatically updated to reflect the committed changes. Closed by commit rL343298: [PDB] Handle `char` as a builtin type (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D52468?vs=166876&id=167433#toc Repository: rL LLVM https://reviews.llvm.org/D52468 Files: lldb/trunk/lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp lldb/trunk/lit/SymbolFile/PDB/ast-restore.test lldb/trunk/lit/SymbolFile/PDB/func-symbols.test lldb/trunk/lit/SymbolFile/PDB/typedefs.test lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp Index: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp === --- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -113,6 +113,8 @@ return CompilerType(); case PDB_BuiltinType::Void: return clang_ast.GetBasicType(eBasicTypeVoid); + case PDB_BuiltinType::Char: +return clang_ast.GetBasicType(eBasicTypeChar); case PDB_BuiltinType::Bool: return clang_ast.GetBasicType(eBasicTypeBool); case PDB_BuiltinType::Long: Index: lldb/trunk/lit/SymbolFile/PDB/ast-restore.test === --- lldb/trunk/lit/SymbolFile/PDB/ast-restore.test +++ lldb/trunk/lit/SymbolFile/PDB/ast-restore.test @@ -58,7 +58,7 @@ INNER: namespace N1 { INNER: class Class : public N0::N1::Base { INNER: struct Inner { -INNER: signed char x; +INNER: char x; INNER: short y; INNER: int z; INNER: }; Index: lldb/trunk/lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp === --- lldb/trunk/lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp +++ lldb/trunk/lit/SymbolFile/PDB/Inputs/SimpleTypesTest.cpp @@ -35,6 +35,9 @@ enum struct EnumStruct { red, blue, black }; EnumStruct EnumStructVar; +typedef signed char SCharTypedef; +SCharTypedef SCVar; + typedef char16_t WChar16Typedef; WChar16Typedef WC16Var; Index: lldb/trunk/lit/SymbolFile/PDB/typedefs.test === --- lldb/trunk/lit/SymbolFile/PDB/typedefs.test +++ lldb/trunk/lit/SymbolFile/PDB/typedefs.test @@ -46,9 +46,10 @@ CHECK-DAG: Type{{.*}} , name = "long", size = 4, compiler_type = {{.*}} long CHECK-DAG: Type{{.*}} , name = "unsigned short", size = 2, compiler_type = {{.*}} unsigned short CHECK-DAG: Type{{.*}} , name = "unsigned int", size = 4, compiler_type = {{.*}} unsigned int +CHECK-DAG: Type{{.*}} , name = "char", size = 1, compiler_type = {{.*}} char CHECK-DAG: Type{{.*}} , name = "signed char", size = 1, compiler_type = {{.*}} signed char -CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} signed char (void *, long, unsigned short, unsigned int, ...) -CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} signed char (*)(void *, long, unsigned short, unsigned int, ...) +CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} char (void *, long, unsigned short, unsigned int, ...) +CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} char (*)(void *, long, unsigned short, unsigned int, ...) CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedef", compiler_type = {{.*}} typedef VarArgsFuncTypedef CHECK-DAG: Type{{.*}} , name = "float", size = 4, compiler_type = {{.*}} float Index: lldb/trunk/lit/SymbolFile/PDB/func-symbols.test === --- lldb/trunk/lit/SymbolFile/PDB/func-symbols.test +++ lldb/trunk/lit/SymbolFile/PDB/func-symbols.test @@ -14,7 +14,7 @@ CHECK-ONE-DAG: [[TY1:.*]]: Type{[[UID1:.*]]} , name = "Func_arg_void", decl = FuncSymbolsTestMain.cpp:4, compiler_type = {{.*}} void (void) CHECK-ONE-DAG: [[TY2:.*]]: Type{[[UID2:.*]]} , name = "Func_arg_none", decl = FuncSymbolsTestMain.cpp:5, compiler_type = {{.*}} void (void) CHECK-ONE-DAG: [[TY3:.*]]: Type{[[UID3:.*]]} , name = "Func_varargs", decl = FuncSymbolsTestMain.cpp:6, compiler_type = {{.*}} void (...) -CHECK-ONE-DAG: [[TY4:.*]]: Type{[[UID4:.*]]} , name = "Func", decl = FuncSymbolsTestMain.cpp:28, compiler_type = {{.*}} void (signed char, int) +CHECK-ONE-DAG: [[TY4:.*]]: Type{[[UID4:.*]]} , name = "Func", decl = FuncSymbolsTestMain.cpp:28, compiler_type = {{.*}} void (char, int) CHECK-ONE-DAG: [[TY5:.*]]: Type{[[UID5:.*]]} , name = "main", decl = FuncSymbolsTestMain.cpp:44, compiler_type = {{.*}} int (void) CHECK-ONE-DAG: [[TY6:.*]]: Type{[[UID6:.*]]} , name = "Func", decl = FuncSymbolsTestMain.cpp:24, compiler_type = {{.*}} void (int, const long, volatile _Bool, ...) CHECK-ONE-DAG: [[TY7:.*]]: Type{[[UID7:.*]]} , name = "StaticFunction", decl = FuncSymbolsTestMain.cpp:35, compiler_type = {{.*}} long (int) Index: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTPar
[Lldb-commits] [PATCH] D52618: [Windows] A basic implementation of memory allocations in a debuggee process
aleksandr.urakov added a comment. Thanks for explanations! Unfortunately I can't promise that I'll begin porting `lldb-server` on Windows in the nearest future. I've looked at my working copy, and there are only two small changes related to `ProcessWindows` plugin (but they are not related to the current review), may be we'll continue with the plugin for now? To proceed with other things that need some implementation of a such functionality (whether in `ProcessWindows` or `lldb-server`). How about this? https://reviews.llvm.org/D52618 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a reviewer: clayborg. aleksandr.urakov added a comment. In https://reviews.llvm.org/D52461#1245058, @clayborg wrote: > Try to use and extend CPlusPlusLanguage::MethodName as needed. I believe it > was recently backed by a new clang parser that knows how to chop up C++ > demangled names It seems that `CPlusPlusLanguage::MethodName` is backed by LLDB `CPlusPlusNameParser`, which can't parse demangled names... Can you tell me, please, how is called a new Clang parser you have mentioned? May be I'll use it directly instead of `PDBNameParser`, or will back `PDBNameParser` by it (if the interface will be not very convenient)? Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a comment. Ok, I'll look at this, thank you! Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a comment. I've tried to parse with it a name like N0::`unnamed namespase'::Name and it can't parse it correctly. May be it just can't parse MSVC demangled names? Unfortunately, I can't look at the tests right now, I have a vacation. I'll look at these a week later, ok? Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, rnk, stella.stamenova. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, abidh, JDevlieghere, aprantl. This patch fixes the flaky test `variables-locations.test`. The test began flaking after the fix of the PR38857 issue. It have happened because in `PDBLocationToDWARFExpression` we treat a `VFRAME` register as a `LLDB_REGNUM_GENERIC_FP`, which leads to `EBP` on Windows x86, but in this case we can't read locals relative to `EBP`. Moreover, it seems that we have no alternative base, so I just have changed `double` with `float` to avoid alignment. By the way, what do you think, how can we make LLDB support aligned stacks? As far as I know, similar alignment problems are reproducible on non-Windows too. Repository: rLLDB LLDB https://reviews.llvm.org/D53086 Files: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp Index: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp === --- lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp +++ lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp @@ -2,7 +2,7 @@ void __fastcall foo(short arg_0, float arg_1) { char loc_0 = 'x'; - double loc_1 = 0.5678; + float loc_1 = 0.5678; } int main(int argc, char *argv[]) { Index: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp === --- lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp +++ lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp @@ -2,7 +2,7 @@ void __fastcall foo(short arg_0, float arg_1) { char loc_0 = 'x'; - double loc_1 = 0.5678; + float loc_1 = 0.5678; } int main(int argc, char *argv[]) { ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov added a comment. Thanks a lot for so detailed answer, it helps! So we need to parse a FPO program and to convert it in a DWARF expression too. The problem here (in the DIA case) is that I don't know how to retrieve the required FPO range (we have a symbol context when creating a variable, but it seems that it doesn't contain enough information). As for the raw PDB case, can the same `S_LOCAL` have several `S_DEFRANGE_FRAMEPOINTER_REL` records for several ranges? If so, then the problem exists for the raw PDB case too, but there's a solution: we can combine processing of all `S_DEFRANGE_FRAMEPOINTER_REL` records in the single DWARF expression (and call the required FPO program depending on current `eip`). The interesting moment here is that MSVC doesn't emit correct information for locals. For the program `aaa.cpp`: void bar(char a, short b, int c) { } void __fastcall foo(short arg_0, float arg_1) { char loc_0 = 'x'; double __declspec(align(8)) loc_1 = 0.5678; bar(1, 2, 3); } int main(int argc, char *argv[]) { foo(, 0.1234); return 0; } compiled with `cl /Zi /Oy aaa.cpp` we have the next disassembly of `foo`: pushebp mov ebp, esp and esp, 0FFF8h sub esp, 10h mov [esp+4], cx ; arg_0 mov byte ptr [esp+3], 'x' ; loc_0 movsd xmm0, ds:__real@3fe22b6ae7d566cf movsd qword ptr [esp+8], xmm0 ; loc_1 push3 ; c push2 ; b push1 ; a callj_?bar@@YAXDFH@Z ; bar(char,short,int) add esp, 0Ch mov esp, ebp pop ebp retn4 but MSVC emits the next info about locals: 296 | S_GPROC32 [size = 44] `foo` parent = 0, end = 452, addr = 0001:23616, code size = 53 type = `0x1003 (void (short, float))`, debug start = 14, debug end = 47, flags = has fp 340 | S_FRAMEPROC [size = 32] size = 16, padding size = 0, offset to padding = 0 bytes of callee saved registers = 0, exception handler addr = : local fp reg = VFRAME, param fp reg = EBP flags = has async eh | opt speed 372 | S_REGREL32 [size = 20] `arg_0` type = 0x0011 (short), register = ESP, offset = 4294967284 392 | S_REGREL32 [size = 20] `arg_1` type = 0x0040 (float), register = EBP, offset = 8 412 | S_REGREL32 [size = 20] `loc_1` type = 0x0041 (double), register = ESP, offset = 4294967288 432 | S_REGREL32 [size = 20] `loc_0` type = 0x0070 (char), register = ESP, offset = 4294967283 452 | S_END [size = 4] so neither LLDB nor Visual Studio show valid values (except for `arg_1`). In https://reviews.llvm.org/D53086#1260787, @zturner wrote: > You didn't include it here, but I notice the test file just writes `clang-cl > /Zi`. Should we be passing `-m32` or `-m64`? Currently, the test just runs > with whatever architecture happens to be set via the VS command prompt. The > behavior here is different on x86 and x64 so perhaps it requires separate > tests. The problem is that x64 LLDB can't debug x86 applications on Windows (and vice versa), so I rely here on the fact that tests are run in the same VS command prompt as LLVM was built. But yes, it's still possible to run tests for x86 LLVM under the x64 VS command prompt, so this one will fail. I think we can somehow guard this when I'll implement `compiler_config` you have mentioned in https://reviews.llvm.org/D52618. In https://reviews.llvm.org/D53086#1260685, @stella.stamenova wrote: > Could you document that in the test? Sure, thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D53086 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov updated this revision to Diff 169181. https://reviews.llvm.org/D53086 Files: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script Index: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script === --- lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script +++ lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script @@ -1,4 +1,4 @@ -breakpoint set --file VariablesLocationsTest.cpp --line 6 +breakpoint set --file VariablesLocationsTest.cpp --line 8 run Index: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp === --- lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp +++ lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp @@ -2,7 +2,9 @@ void __fastcall foo(short arg_0, float arg_1) { char loc_0 = 'x'; - double loc_1 = 0.5678; + // TODO: make it double when FPO support in `PDBLocationToDWARFExpression` + // will be implemented + float loc_1 = 0.5678; } int main(int argc, char *argv[]) { Index: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script === --- lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script +++ lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.script @@ -1,4 +1,4 @@ -breakpoint set --file VariablesLocationsTest.cpp --line 6 +breakpoint set --file VariablesLocationsTest.cpp --line 8 run Index: lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp === --- lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp +++ lit/SymbolFile/PDB/Inputs/VariablesLocationsTest.cpp @@ -2,7 +2,9 @@ void __fastcall foo(short arg_0, float arg_1) { char loc_0 = 'x'; - double loc_1 = 0.5678; + // TODO: make it double when FPO support in `PDBLocationToDWARFExpression` + // will be implemented + float loc_1 = 0.5678; } int main(int argc, char *argv[]) { ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov added subscribers: zturner, jasonmolenda, labath. aleksandr.urakov added a comment. As for aligned stack cross-platform problems, I mean also problems with stack unwinding. They seem to appear on non-Windows too. It's because `x86AssemblyInspectionEngine` doesn't support stack alignment now. I've made some changes locally to fix it, but they are still raw to publish. The main idea is to save one more frame address (along with CFA) for every row of an unwind plan (I've called this AFA - aligned frame address), and add an analysis for `and esp, ...` etc. to `x86AssemblyInspectionEngine`. What do you think about a such approach? https://reviews.llvm.org/D53086 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53092: [lldb] Add support in Status::AsCString to retrieve win32 system error strings
aleksandr.urakov added a comment. Otherwise LGTM! Comment at: unittests/Utility/StatusTest.cpp:68-74 + EXPECT_STREQ("Access is denied. ", s.AsCString()); + + s.SetError(ERROR_IPSEC_IKE_TIMED_OUT, ErrorType::eErrorTypeWin32); + EXPECT_STREQ("Negotiation timed out ", s.AsCString()); + + s.SetError(16000, ErrorType::eErrorTypeWin32); + EXPECT_STREQ("unknown error", s.AsCString()); I'm not sure, can we rely on the fact that messages are the same in different versions of Windows? Repository: rLLDB LLDB https://reviews.llvm.org/D53092 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53094: [pecoff] Implement ObjectFilePECOFF::GetDependedModules()
aleksandr.urakov added inline comments. Comment at: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp:801-804 + if (m_filespec_ap.get()) +return m_filespec_ap->GetSize(); + + m_filespec_ap.reset(new FileSpecList()); I'm afraid of a race condition here. It seems we can occur here in different threads simultaneously (due to the mutex lock at the line 810), but it is not thread-safe to change and read //same// unique_ptr in different threads simultaneously. It is safe to //move// it between threads, but it's not the case. I would guard all actions on unique_ptr with the mutex. Comment at: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp:881-885 + auto num_modules = ParseDependentModules(); + auto original_size = files.GetSize(); + + for (unsigned i = 0; i < num_modules; ++i) +files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)); Also consider the following scenario: `Thread A`: `GetDependentModules` -> `ParseDependentModules` -> e.g. line 837, `idx` is greater than `0`, but less than `num_entries`; `Thread B`: `GetDependentModules` (or `DumpDependentModules`) -> `ParseDependentModules` -> `ParseDependentModules` returns `num_modules` less than actual; `Thread A`: continues to write into `m_filespec_ap`; `Thread B`: reads `m_filespec_ap` which is modified at the time by `Thread A`. Comment at: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp:1100-1104 + auto num_modules = ParseDependentModules(); + if (num_modules > 0) { +s->PutCString("Dependent Modules\n"); +for (unsigned i = 0; i < num_modules; ++i) { + auto spec = m_filespec_ap->GetFileSpecAtIndex(i); The same situation as I've described above. Repository: rLLDB LLDB https://reviews.llvm.org/D53094 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53096: [lldb-test] Add a lit test for dependent modules in PECOFF
aleksandr.urakov accepted this revision. aleksandr.urakov added a comment. This revision is now accepted and ready to land. LGTM after https://reviews.llvm.org/D53094 will be done! Repository: rLLDB LLDB https://reviews.llvm.org/D53096 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov added a comment. In https://reviews.llvm.org/D53086#1263002, @zturner wrote: > Do we have access to the current instruction pointer? That's what you need > to find the correct FPO record. No, it seems that we haven't. But if there's the only one `S_DEFRANGE_FRAMEPOINTER_REL` for variable, then there must be the only one definition of `VFRAME` for the variable's range, and then I think we can safely search the required FPO data by intersection with the variable's scope range. I'll try to implement this, thanks! https://reviews.llvm.org/D53086 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a subscriber: labath. aleksandr.urakov added a comment. Hello! I just have tried to patch `CPlusPlusNameParser` in the way to support MSVC demangled names, but there is a problem. `CPlusPlusNameParser` splits an incoming name in tokens with `clang::Lexer`. I've lexed the next name: `anonymous namespace'::foo The lexer treats the first character (a grave accent) as an unknown token, and it's ok for our purposes. Then it sees an identifier (`anonymous`), a keyword (`namespace`), and it's ok too. But the problem is with the last part of the string. The lexer sees an apostrophe and supposes that it's a character constant, it looks for a closing apostrophe, don't find it and treats all the line ending (`'::foo`) as a single unknown token. It is possible to somehow make `clang::Lexer` lex MSVC demangled names correctly, but I'm not sure if it is the right place to do it. And it may have then some side effects during lexing a real code. Another option is to somehow preprocess the name before lexing and replace all //paired// apostrophes with grave accents, and after lexing replace with apostrophes back, and make `CPlusPlusNameParser` understand unknown grave accent tokens. But it's a bit tricky, may be you can suggest some better solution? Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a comment. In https://reviews.llvm.org/D52461#1265633, @zturner wrote: > Just handle the `anonymous namespace' thing specially before passing to > `CPlusPlusNameParser`. Yes, it's an interesting idea to somehow preprocess an MSVC demangled name and make a GCC demangled name from it (and make an MSVC-like name back after parsing). But then we need to handle not only anonymous namespaces, also things like this: `operator<'::`2'::B::operator> Such a preprocessing will be comparable to the current implementation of `PDBNameParser` by complexity (or even more complex). I'll try to somehow estimate the complexity of this approach, thanks. Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov added a comment. Yes, I mean exactly the same case. For sequences like you've written yes, the unwind should work, but there must be some problems with saved registers. `x86AssemblyInspectionEngine` doesn't handle instructions like `and %-8, %esp`, so the register save would work only if this instruction hadn't changed the `esp` value (e.g. `esp` was already aligned). Otherwise, if `esp` was changed, the offset to CFA in `RegisterLocation` of some register will be invalid, because it will not take the alignment into account. Moreover, it is impossible to specify a location for some saved register on a such stack with the `CFA + offset` restore type, because we can't know how `esp` will be changed after `and %-8, %esp`. So I suggest to introduce one more frame address (along with CFA), and make it point to `esp` right after `and ..., %esp`. So any saved register would have `AFA + offset` restore type (I've called for now this frame address as AFA - aligned frame address). As for MSVC-compiled sources, the things are even more interesting. Consider the following program: https://reviews.llvm.org/D53086 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `PDBNameParser`
aleksandr.urakov added a comment. Yes, it's simpler to move it to the `CPlusPlusLanguage::MethodName` (or `CPlusPlusNameParser`?) I think. The only question left is how to differentiate MSVC demangled names from others? May be it would be ok to treat name as an MSVC name if it contains a grave accent? Because we probably already can parse MSVC names without grave accents with `CPlusPlusLanguage::MethodName`. Repository: rLLDB LLDB https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53357: [Windows] Fix threads comparison on Windows
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, clayborg. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits. This patch makes Windows threads to compare by a thread ID, not by a handle. It's because the same thread can have different handles on Windows (for example, `GetCurrentThread` always returns the fake handle `-2`). This leads to some incorrect behavior. For example, in `Process::GetRunLock` always `m_public_run_lock` is returned without this patch. Repository: rLLDB LLDB https://reviews.llvm.org/D53357 Files: include/lldb/Host/HostNativeThreadBase.h include/lldb/Host/windows/HostThreadWindows.h source/Host/common/HostNativeThreadBase.cpp source/Host/common/HostThread.cpp source/Host/windows/HostThreadWindows.cpp Index: source/Host/windows/HostThreadWindows.cpp === --- source/Host/windows/HostThreadWindows.cpp +++ source/Host/windows/HostThreadWindows.cpp @@ -69,3 +69,7 @@ HostNativeThreadBase::Reset(); } + +bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const { + return GetThreadId() == ::GetThreadId(thread); +} Index: source/Host/common/HostThread.cpp === --- source/Host/common/HostThread.cpp +++ source/Host/common/HostThread.cpp @@ -43,5 +43,5 @@ } bool HostThread::EqualsThread(lldb::thread_t thread) const { - return m_native_thread->GetSystemHandle() == thread; + return m_native_thread->EqualsThread(thread); } Index: source/Host/common/HostNativeThreadBase.cpp === --- source/Host/common/HostNativeThreadBase.cpp +++ source/Host/common/HostNativeThreadBase.cpp @@ -41,6 +41,10 @@ m_result = 0; } +bool HostNativeThreadBase::EqualsThread(lldb::thread_t thread) const { + return m_thread == thread; +} + lldb::thread_t HostNativeThreadBase::Release() { lldb::thread_t result = m_thread; m_thread = LLDB_INVALID_HOST_THREAD; Index: include/lldb/Host/windows/HostThreadWindows.h === --- include/lldb/Host/windows/HostThreadWindows.h +++ include/lldb/Host/windows/HostThreadWindows.h @@ -29,6 +29,7 @@ virtual Status Join(lldb::thread_result_t *result); virtual Status Cancel(); virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::tid_t GetThreadId() const; Index: include/lldb/Host/HostNativeThreadBase.h === --- include/lldb/Host/HostNativeThreadBase.h +++ include/lldb/Host/HostNativeThreadBase.h @@ -35,6 +35,7 @@ virtual Status Cancel() = 0; virtual bool IsJoinable() const; virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::thread_t Release(); lldb::thread_t GetSystemHandle() const; Index: source/Host/windows/HostThreadWindows.cpp === --- source/Host/windows/HostThreadWindows.cpp +++ source/Host/windows/HostThreadWindows.cpp @@ -69,3 +69,7 @@ HostNativeThreadBase::Reset(); } + +bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const { + return GetThreadId() == ::GetThreadId(thread); +} Index: source/Host/common/HostThread.cpp === --- source/Host/common/HostThread.cpp +++ source/Host/common/HostThread.cpp @@ -43,5 +43,5 @@ } bool HostThread::EqualsThread(lldb::thread_t thread) const { - return m_native_thread->GetSystemHandle() == thread; + return m_native_thread->EqualsThread(thread); } Index: source/Host/common/HostNativeThreadBase.cpp === --- source/Host/common/HostNativeThreadBase.cpp +++ source/Host/common/HostNativeThreadBase.cpp @@ -41,6 +41,10 @@ m_result = 0; } +bool HostNativeThreadBase::EqualsThread(lldb::thread_t thread) const { + return m_thread == thread; +} + lldb::thread_t HostNativeThreadBase::Release() { lldb::thread_t result = m_thread; m_thread = LLDB_INVALID_HOST_THREAD; Index: include/lldb/Host/windows/HostThreadWindows.h === --- include/lldb/Host/windows/HostThreadWindows.h +++ include/lldb/Host/windows/HostThreadWindows.h @@ -29,6 +29,7 @@ virtual Status Join(lldb::thread_result_t *result); virtual Status Cancel(); virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::tid_t GetThreadId() const; Index: include/lldb/Host/HostNativeThreadBase.h === --- include/lldb/Host/HostNativeThreadBase.h +++ include/lldb/Host/HostNativeThreadBase.h @@ -35,6 +35,7 @@ virtual Status Cancel() = 0; virtual bool IsJoinable() const; virtual void Reset(); + vi
[Lldb-commits] [PATCH] D53361: [API] Extend the `SBThreadPlan` interface
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: labath, zturner, jingham. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits. This patch extends the `SBThreadPlan` to allow retrieving of thread plans for scripted steps. Repository: rLLDB LLDB https://reviews.llvm.org/D53361 Files: include/lldb/API/SBThreadPlan.h scripts/interface/SBThreadPlan.i source/API/SBThreadPlan.cpp Index: source/API/SBThreadPlan.cpp === --- source/API/SBThreadPlan.cpp +++ source/API/SBThreadPlan.cpp @@ -207,3 +207,13 @@ return SBThreadPlan(); } } + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) { + if (m_opaque_sp) { +return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( +false, script_class_name, false)); + } else { +return SBThreadPlan(); + } +} Index: scripts/interface/SBThreadPlan.i === --- scripts/interface/SBThreadPlan.i +++ scripts/interface/SBThreadPlan.i @@ -106,6 +106,9 @@ SBThreadPlan QueueThreadPlanForRunToAddress (SBAddress address); +SBThreadPlan +QueueThreadPlanForStepScripted(const char *script_class_name); + protected: friend class SBBreakpoint; Index: include/lldb/API/SBThreadPlan.h === --- include/lldb/API/SBThreadPlan.h +++ include/lldb/API/SBThreadPlan.h @@ -88,6 +88,8 @@ SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address); + SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name); + #ifndef SWIG lldb_private::ThreadPlan *get(); #endif Index: source/API/SBThreadPlan.cpp === --- source/API/SBThreadPlan.cpp +++ source/API/SBThreadPlan.cpp @@ -207,3 +207,13 @@ return SBThreadPlan(); } } + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) { + if (m_opaque_sp) { +return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( +false, script_class_name, false)); + } else { +return SBThreadPlan(); + } +} Index: scripts/interface/SBThreadPlan.i === --- scripts/interface/SBThreadPlan.i +++ scripts/interface/SBThreadPlan.i @@ -106,6 +106,9 @@ SBThreadPlan QueueThreadPlanForRunToAddress (SBAddress address); +SBThreadPlan +QueueThreadPlanForStepScripted(const char *script_class_name); + protected: friend class SBBreakpoint; Index: include/lldb/API/SBThreadPlan.h === --- include/lldb/API/SBThreadPlan.h +++ include/lldb/API/SBThreadPlan.h @@ -88,6 +88,8 @@ SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address); + SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name); + #ifndef SWIG lldb_private::ThreadPlan *get(); #endif ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, asmith, labath. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits. This patch adds possibility of searching a public symbol with name and type in a symbol file, not only in a symtab. It is helpful when working with PE, because PE's symtabs contain only imported / exported symbols only. Such a search is required for e.g. evaluation of an expression that calls some function of the debuggee. A few weeks ago on `lldb-dev` there was a discussion of this, it is called `Symtab for PECOFF`. Repository: rLLDB LLDB https://reviews.llvm.org/D53368 Files: include/lldb/Symbol/SymbolFile.h include/lldb/Symbol/SymbolVendor.h include/lldb/lldb-forward.h source/Core/Module.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h source/Symbol/SymbolFile.cpp source/Symbol/SymbolVendor.cpp unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -615,3 +615,20 @@ EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared(fspec, aspec); + + SymbolContextList sc_list; + EXPECT_EQ(1u, +module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), + lldb::eSymbolTypeAny, sc_list)); + EXPECT_EQ(1u, sc_list.GetSize()); + + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_STREQ("int foo(int)", + sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); +} Index: source/Symbol/SymbolVendor.cpp === --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -314,6 +314,18 @@ return 0; } +size_t SymbolVendor::FindPublicSymbols(const ConstString &name, + lldb::SymbolType type, bool append, + SymbolContextList &sc_list) { + ModuleSP module_sp(GetModule()); + if (module_sp) { +std::lock_guard guard(module_sp->GetMutex()); +if (m_sym_file_ap.get()) + return m_sym_file_ap->FindPublicSymbols(name, type, append, sc_list); + } + return 0; +} + size_t SymbolVendor::FindTypes( const SymbolContext &sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, Index: source/Symbol/SymbolFile.cpp === --- source/Symbol/SymbolFile.cpp +++ source/Symbol/SymbolFile.cpp @@ -127,6 +127,14 @@ return 0; } +size_t SymbolFile::FindPublicSymbols(const ConstString &name, + lldb::SymbolType type, bool append, + SymbolContextList &sc_list) { + if (!append) +sc_list.Clear(); + return 0; +} + void SymbolFile::GetMangledNamesForFunction( const std::string &scope_qualified_name, std::vector &mangled_names) { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -132,6 +132,10 @@ const std::string &scope_qualified_name, std::vector &mangled_names) override; + size_t FindPublicSymbols(const lldb_private::ConstString &name, + lldb::SymbolType type, bool append, + lldb_private::SymbolContextList &sc_list) override; + uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, @@ -227,9 +231,13 @@ bool DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx); + lldb_private::Symbol * + GetPublicSymbol(const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_symbols; std::vector m_builtin_types; std::unique_ptr m_session_up; Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1339,6 +1339,42 @@ const std::string &scope_qualified_name, std::vector &mangled_names) {} +size_t +SymbolFilePDB::FindPublicSymbols(const lldb_private::ConstString &name, + lldb::SymbolType type, bool append, +
[Lldb-commits] [PATCH] D53375: [PDB] Improve performance of the PDB DIA plugin
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, asmith, labath. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits. This patch improves performance of `SymbolFilePDB` on huge executables in two ways: - cache names of public symbols by address. When creating variables we are trying to get a mangled name for each one, and in `GetMangledForPDBData` we are enumerating all public symbols, which takes O(n) for each variable. With the cache we can retrieve a mangled name in O(log(n)); - cache section contributions. When parsing variables for context we are enumerating all variables and check if the current one is belonging to the current compiland. So we are retrieving a compiland ID for the variable. But in `PDBSymbolData::getCompilandId` for almost every variable we are enumerating all section contributions to check if the variable is belonging to it, and get a compiland ID from the section contribution if so. It takes O(n) for each variable, but with caching it takes about O(log(n)). I've placed the cache in `SymbolFilePDB` and have created `GetCompilandId` there. It actually duplicates `PDBSymbolData::getCompilandId` except for the cache part. Another option is to support caching in `PDBSymbolData::getCompilandId` and to place cache in `DIASession`, but it seems that the last one doesn't imply such functionality, because it's a lightweight wrapper over DIA and whole its state is only a COM pointer to the DIA session. Moreover, `PDBSymbolData::getCompilandId` is used only inside of `SymbolFilePDB`, so I think that it's not a bad place to do such things. With this patch `PDBSymbolData::getCompilandId` is not used at all. This bottlenecks were found with profiling. I've discovered these on a simple demo project of Unreal Engine (x86 executable ~72M, PDB ~82M). This patch doesn't change external behavior of the plugin, so I think that there's no need for additional testing (already existing tests should warn us about regress, if any). Repository: rLLDB LLDB https://reviews.llvm.org/D53375 Files: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -169,6 +169,13 @@ const llvm::pdb::IPDBSession &GetPDBSession() const; private: + struct SecContribInfo { +uint32_t Offset; +uint32_t Size; +uint32_t CompilandId; + }; + using SecContribsMap = std::map>; + lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id, uint32_t index = UINT32_MAX); @@ -227,9 +234,14 @@ bool DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx); + uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_names; + + SecContribsMap m_sec_contribs; std::vector m_builtin_types; std::unique_ptr m_session_up; Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -534,7 +534,7 @@ auto results = m_global_scope_up->findAllChildren(); if (results && results->getChildCount()) { while (auto result = results->getNext()) { -auto cu_id = result->getCompilandId(); +auto cu_id = GetCompilandId(*result); // FIXME: We are not able to determine variable's compile unit. if (cu_id == 0) continue; @@ -853,24 +853,16 @@ } std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) { - std::string decorated_name; - auto vm_addr = pdb_data.getVirtualAddress(); - if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) { -auto result_up = -m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol); -if (result_up) { - while (auto symbol_up = result_up->getNext()) { -if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) { - decorated_name = symbol_up->getRawSymbol().getName(); - break; -} - } -} - } - if (!decorated_name.empty()) -return decorated_name; - - return std::string(); + // Cache public names at first + if (m_public_names.empty()) +if (auto result_up = +m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol)) + while (auto symbol_up = result_up->getNext()) +if (auto addr = symbol_up->getRawSymbol().getVirtualAddress()) + m_public_names[addr] = symbol_up->getRawSymbol().getName(); + + // Look up the name in the cache + return m_public_names.lookup(pdb_data.getVirtualAddress()); } Varia
[Lldb-commits] [PATCH] D53357: [Windows] Fix threads comparison on Windows
aleksandr.urakov added a comment. Thank you! Repository: rLLDB LLDB https://reviews.llvm.org/D53357 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53357: [Windows] Fix threads comparison on Windows
This revision was automatically updated to reflect the committed changes. Closed by commit rL344729: [Windows] Fix threads comparison on Windows (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53357?vs=169966&id=170047#toc Repository: rL LLVM https://reviews.llvm.org/D53357 Files: lldb/trunk/include/lldb/Host/HostNativeThreadBase.h lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h lldb/trunk/source/Host/common/HostNativeThreadBase.cpp lldb/trunk/source/Host/common/HostThread.cpp lldb/trunk/source/Host/windows/HostThreadWindows.cpp Index: lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h === --- lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h +++ lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h @@ -29,6 +29,7 @@ virtual Status Join(lldb::thread_result_t *result); virtual Status Cancel(); virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::tid_t GetThreadId() const; Index: lldb/trunk/include/lldb/Host/HostNativeThreadBase.h === --- lldb/trunk/include/lldb/Host/HostNativeThreadBase.h +++ lldb/trunk/include/lldb/Host/HostNativeThreadBase.h @@ -35,6 +35,7 @@ virtual Status Cancel() = 0; virtual bool IsJoinable() const; virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::thread_t Release(); lldb::thread_t GetSystemHandle() const; Index: lldb/trunk/source/Host/windows/HostThreadWindows.cpp === --- lldb/trunk/source/Host/windows/HostThreadWindows.cpp +++ lldb/trunk/source/Host/windows/HostThreadWindows.cpp @@ -69,3 +69,7 @@ HostNativeThreadBase::Reset(); } + +bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const { + return GetThreadId() == ::GetThreadId(thread); +} Index: lldb/trunk/source/Host/common/HostNativeThreadBase.cpp === --- lldb/trunk/source/Host/common/HostNativeThreadBase.cpp +++ lldb/trunk/source/Host/common/HostNativeThreadBase.cpp @@ -41,6 +41,10 @@ m_result = 0; } +bool HostNativeThreadBase::EqualsThread(lldb::thread_t thread) const { + return m_thread == thread; +} + lldb::thread_t HostNativeThreadBase::Release() { lldb::thread_t result = m_thread; m_thread = LLDB_INVALID_HOST_THREAD; Index: lldb/trunk/source/Host/common/HostThread.cpp === --- lldb/trunk/source/Host/common/HostThread.cpp +++ lldb/trunk/source/Host/common/HostThread.cpp @@ -43,5 +43,5 @@ } bool HostThread::EqualsThread(lldb::thread_t thread) const { - return m_native_thread->GetSystemHandle() == thread; + return m_native_thread->EqualsThread(thread); } Index: lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h === --- lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h +++ lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h @@ -29,6 +29,7 @@ virtual Status Join(lldb::thread_result_t *result); virtual Status Cancel(); virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::tid_t GetThreadId() const; Index: lldb/trunk/include/lldb/Host/HostNativeThreadBase.h === --- lldb/trunk/include/lldb/Host/HostNativeThreadBase.h +++ lldb/trunk/include/lldb/Host/HostNativeThreadBase.h @@ -35,6 +35,7 @@ virtual Status Cancel() = 0; virtual bool IsJoinable() const; virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::thread_t Release(); lldb::thread_t GetSystemHandle() const; Index: lldb/trunk/source/Host/windows/HostThreadWindows.cpp === --- lldb/trunk/source/Host/windows/HostThreadWindows.cpp +++ lldb/trunk/source/Host/windows/HostThreadWindows.cpp @@ -69,3 +69,7 @@ HostNativeThreadBase::Reset(); } + +bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const { + return GetThreadId() == ::GetThreadId(thread); +} Index: lldb/trunk/source/Host/common/HostNativeThreadBase.cpp === --- lldb/trunk/source/Host/common/HostNativeThreadBase.cpp +++ lldb/trunk/source/Host/common/HostNativeThreadBase.cpp @@ -41,6 +41,10 @@ m_result = 0; } +bool HostNativeThreadBase::EqualsThread(lldb::thread_t thread) const { + return m_thread == thread; +} + lldb::thread_t HostNativeThreadBase::Release() { lldb::thread_t result = m_thread; m_thread = LLDB_INVALID_HOST_THREAD; Index: lldb/trunk/source/Host/common/HostThread.cpp ==
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov added a comment. In https://reviews.llvm.org/D53086#1267988, @labath wrote: > The thing that's not clear to me is: are you specifically interested in > unwinding from these kinds of functions **without debug info**? Because it > sounds to me like the info Zachary provided is enough to unwind from these > functions, assuming debug info is present. And in this case there shouldn't > be any need for instruction emulation. Yes, it seems that the info is enough to restore some of unwind plan rows, but not all of them. Here is an FPO table for the code above (compiled with `cl /Zi /GS- /c a.cpp`, linked with `link /nodefaultlib /debug:full /entry:main a.obj`): New FPO Data RVA| Code | Locals | Params | Stack | Prolog | Saved Regs | Has SEH | Has C++EH | Start | Program 1030 | 52 |512 | 4 | 0 | 31 | 0 | false | false | true | $T0 $ebp = $T1 $ebx = $eip $T1 4 + ^ = $ebx $T1 ^ = $esp $T1 8 + = $ebp $ebp ^ = 1070 | 65 |512 | 4 | 0 | 31 | 0 | false | false | true | $T0 $ebp = $T1 $ebx = $eip $T1 4 + ^ = $ebx $T1 ^ = $esp $T1 8 + = $ebp $ebp ^ = 10C0 | 20 | 0 | 0 | 0 | 3 | 0 | false | false | true | $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = `1030` is the RVA of `foo`, `1070` - `bar`, `10C0` - `main`. So we can restore unwind rows for each function except for prologues and epilogues (however, I think that such restore is not so trivial too, we need to parse and convert an FPO program into a DWARF expression for each register). For prologues and epilogues we need to emulate instructions. And what about the problem with saved registers I've mentioned above? It seems exist on non-Windows too, and (correct me if I'm wrong, please) the unwind plan is restored from instruction emulation there for such cases? So we still need to support this in `x86AssemblyInspectionEngine`? https://reviews.llvm.org/D53086 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53435: [x86] Fix issues with a realigned stack in MSVC compiled applications
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: labath, zturner, jasonmolenda, stella.stamenova. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, abidh. This patch fixes issues with a stack realignment. MSVC maintains two frame pointers (`ebx` and `ebp`) for a realigned stack - one is used for access to function parameters, while another is used for access to locals. To support this the patch: - adds an alternative frame pointer (`ebx`); - considers stack realignment instructions (e.g. `and esp, -32`); - along with CFA (Canonical Frame Address) which point to the position next to the saved return address (or to the first parameter on the stack) introduces AFA (Aligned Frame Address) which points to the position of the stack pointer right after realignment. AFA is used for access to registers saved after the realignment (see the test); Here is an example of the code with the realignment: struct __declspec(align(256)) OverAligned { char c; }; void foo(int foo_arg) { OverAligned oa_foo = { 1 }; auto aaa_foo = 1234; } void bar(int bar_arg) { OverAligned oa_bar = { 2 }; auto aaa_bar = 5678; foo(); } int main() { bar(); return 0; } and here is the `bar` disassembly: pushebx mov ebx, esp sub esp, 8 and esp, -100h add esp, 4 pushebp mov ebp, [ebx+4] mov [esp+4], ebp mov ebp, esp sub esp, 200h mov byte ptr [ebp-200h], 2 mov dword ptr [ebp-4], 5678 push; foo_arg callj_?foo@@YAXH@Z ; foo(int) add esp, 4 mov esp, ebp pop ebp mov esp, ebx pop ebx retn Btw, it seems that the code of `x86AssemblyInspectionEngine` has overgrown. I have some ideas how to refactor this, if you don't mind I can do it in the future? https://reviews.llvm.org/D53086 also contains some discussion on the topic. Repository: rLLDB LLDB https://reviews.llvm.org/D53435 Files: include/lldb/Symbol/UnwindPlan.h source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Plugins/Process/Utility/RegisterContextLLDB.h source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h source/Symbol/UnwindPlan.cpp unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Index: unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp === --- unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp @@ -133,7 +133,7 @@ namespace lldb_private { static std::ostream &operator<<(std::ostream &OS, -const UnwindPlan::Row::CFAValue &CFA) { +const UnwindPlan::Row::FAValue &CFA) { StreamString S; CFA.Dump(S, nullptr, nullptr); return OS << S.GetData(); @@ -2368,7 +2368,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue esp_plus_4, esp_plus_8, ebp_plus_8; + UnwindPlan::Row::FAValue esp_plus_4, esp_plus_8, ebp_plus_8; esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); ebp_plus_8.SetIsRegisterPlusOffset(k_ebp, 8); @@ -2402,7 +2402,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; + UnwindPlan::Row::FAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; rsp_plus_8.SetIsRegisterPlusOffset(k_rsp, 8); rsp_plus_16.SetIsRegisterPlusOffset(k_rsp, 16); rbp_plus_16.SetIsRegisterPlusOffset(k_rbp, 16); @@ -2416,6 +2416,65 @@ plan.GetRowForFunctionOffset(sizeof(data) - 1)->GetCFAValue()); } +TEST_F(Testx86AssemblyInspectionEngine, TestStackRealignMSVC_i386) { + std::unique_ptr engine = Geti386Inspector(); + + uint8_t data[] = { + 0x53, // offset 00 -- pushl %ebx + 0x8b, 0xdc, // offset 01 -- movl %esp, %ebx + 0x83, 0xec, 0x08, // offset 03 -- subl $8, %esp + 0x81, 0xe4, 0x00, 0xff, 0xff, 0xff, // offset 06 -- andl $-256, %esp + 0x83, 0xc4, 0x04, // offset 12 -- addl $4, %esp + 0x55, // offset 15 -- pushl %ebp + 0x8b, 0xec, // offset 16 -- movl %esp, %ebp + 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // offset 18 -- subl $512, %esp + 0x89, 0x7d, 0xfc, // offset 24 -- movl %edi, -4(%ebp) + 0x8b, 0xe5, // offset 27 -- movl %ebp,
[Lldb-commits] [PATCH] D53375: [PDB] Improve performance of the PDB DIA plugin
aleksandr.urakov added a comment. Thank you! Repository: rLLDB LLDB https://reviews.llvm.org/D53375 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53361: [API] Extend the `SBThreadPlan` interface
aleksandr.urakov added a comment. Thanks! Yes, I've added this exactly to allow usage of a scripted plan from another scripted plan. Sure, I will add a test for this :) But I can't figure out how this part is tested, can you explain me this a little, please? Repository: rLLDB LLDB https://reviews.llvm.org/D53361 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857
aleksandr.urakov added a comment. Thanks for explanations! I completely agree with you that it were better (and simpler) to implement it with the help of debug info. And if I will improve it later, I'll also choose the way you have described. But the problem is that this sketch was made a couple of months ago, and it seems work, so may be it is not a so bad idea to use it (and not redo it now to work with a debug info)? Besides, in ideal implementation we would still need something like this to cover that rare cases with prologues and epilogues. I've been stashing a lot of changes for past few months, and now the stash is big enough, so I'm trying to send it all on review. Now I understand that it's not a good strategy :) The such approach makes inconvenient situations like this, so I think it is better to send reviews as soon as possible. Sorry for that. I've brushed the sketch and have sent it for review last week, here it is: https://reviews.llvm.org/D53435 https://reviews.llvm.org/D53086 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53506: [ClangASTContext] Extract VTable pointers from C++ objects
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: clayborg, labath, granata.enrico. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor, abidh. This patch processes the case of retrieving a virtual base when the object is already read from the debuggee memory. To achieve that `ValueObject::GetCPPVTableAddress` was removed (btw, it really returned not a C++ VTable address but an object's address, which is a C++ VTable **pointer** address for Itanium, but have nothing to do with VTable address for MSVC) and was reimplemented in `ClangASTContext` (because access to the process is needed to retrieve the VTable pointer in general, and because this is the only place that used old version of `ValueObject::GetCPPVTableAddress`). This patch allows to use real object's VTable instead of searching virtual bases by offsets restored by `MicrosoftRecordLayoutBuilder`. PDB has no enough info to restore VBase offsets properly, so we have to read real VTable instead. This patch depends on https://reviews.llvm.org/D53497 Repository: rLLDB LLDB https://reviews.llvm.org/D53506 Files: include/lldb/Core/ValueObject.h lit/SymbolFile/PDB/Inputs/VBases.cpp lit/SymbolFile/PDB/Inputs/VBases.script lit/SymbolFile/PDB/vbases.test source/Core/ValueObject.cpp source/Symbol/ClangASTContext.cpp Index: source/Symbol/ClangASTContext.cpp === --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -204,6 +204,122 @@ } } +static lldb::addr_t GetVTableAddress(Process &process, + VTableContextBase &vtable_ctx, + ValueObject &valobj, + const ASTRecordLayout &record_layout) { + // Retrieve type info + CompilerType pointee_type; + CompilerType this_type(valobj.GetCompilerType()); + uint32_t type_info = this_type.GetTypeInfo(&pointee_type); + if (!type_info) +return LLDB_INVALID_ADDRESS; + + // Check if it's a pointer or reference + bool ptr_or_ref = false; + if (type_info & (eTypeIsPointer | eTypeIsReference)) { +ptr_or_ref = true; +type_info = pointee_type.GetTypeInfo(); + } + + // We process only C++ classes + const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus; + if ((type_info & cpp_class) != cpp_class) +return LLDB_INVALID_ADDRESS; + + // Calculate offset to VTable pointer + lldb::offset_t vbtable_ptr_offset = + vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity() + : 0; + + if (ptr_or_ref) { +// We have a pointer / ref to object, so read +// VTable pointer from process memory + +if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad) + return LLDB_INVALID_ADDRESS; + +auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); +if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS) + return LLDB_INVALID_ADDRESS; + +vbtable_ptr_addr += vbtable_ptr_offset; + +Status err; +return process.ReadPointerFromMemory(vbtable_ptr_addr, err); + } + + // We have an object already read from process memory, + // so just extract VTable pointer from it + + DataExtractor data; + Status err; + auto size = valobj.GetData(data, err); + if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size) +return LLDB_INVALID_ADDRESS; + + return data.GetPointer(&vbtable_ptr_offset); +} + +static int64_t ReadVBaseOffsetFromVTable(Process &process, + VTableContextBase &vtable_ctx, + lldb::addr_t vtable_ptr, + const CXXRecordDecl *cxx_record_decl, + const CXXRecordDecl *base_class_decl) { + if (vtable_ctx.isMicrosoft()) { +clang::MicrosoftVTableContext &msoft_vtable_ctx = +static_cast(vtable_ctx); + +// Get the index into the virtual base table. The +// index is the index in uint32_t from vbtable_ptr +const unsigned vbtable_index = +msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl); +const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4; +Status err; +return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX, + err); + } + + clang::ItaniumVTableContext &itanium_vtable_ctx = + static_cast(vtable_ctx); + + clang::CharUnits base_offset_offset = + itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl, +base_class_decl); + const lldb::addr_t base_offset_addr = + vtable_ptr + base_offset_offset.getQuantity(); + const uint32_t base_offset_size = process.GetAddressByteSize(); + Status err; + return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset
[Lldb-commits] [PATCH] D53506: [ClangASTContext] Extract VTable pointers from C++ objects
aleksandr.urakov added a comment. In https://reviews.llvm.org/D53506#1270893, @zturner wrote: > What's missing that you're unable to restore the VBase offset properly? If I understand correctly, in the PDB there is only info about offset to VTablePtr and index in VTable, so there is enough info to retrieve VBase offset fairly, and we do it in that way. But there's no info in PDB about offset to VBase directly from object. This info is used when the "fair" doesn't work (e.g. at line 6640). This patch just makes the "fair" way to work in more cases. Repository: rLLDB LLDB https://reviews.llvm.org/D53506 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53375: [PDB] Improve performance of the PDB DIA plugin
aleksandr.urakov added a comment. In https://reviews.llvm.org/D53375#1271336, @Hui wrote: > I think parsing types e.g. SymbolFilePDB::ParseTypes also has speed bumps. > Will be good to have them cached too. We are already caching them, see `m_types` field. Repository: rLLDB LLDB https://reviews.llvm.org/D53375 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53375: [PDB] Improve performance of the PDB DIA plugin
This revision was automatically updated to reflect the committed changes. Closed by commit rL345013: [PDB] Improve performance of the PDB DIA plugin (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53375?vs=170004&id=170584#toc Repository: rL LLVM https://reviews.llvm.org/D53375 Files: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -169,6 +169,13 @@ const llvm::pdb::IPDBSession &GetPDBSession() const; private: + struct SecContribInfo { +uint32_t Offset; +uint32_t Size; +uint32_t CompilandId; + }; + using SecContribsMap = std::map>; + lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id, uint32_t index = UINT32_MAX); @@ -227,9 +234,14 @@ bool DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx); + uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_names; + + SecContribsMap m_sec_contribs; std::vector m_builtin_types; std::unique_ptr m_session_up; Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -534,7 +534,7 @@ auto results = m_global_scope_up->findAllChildren(); if (results && results->getChildCount()) { while (auto result = results->getNext()) { -auto cu_id = result->getCompilandId(); +auto cu_id = GetCompilandId(*result); // FIXME: We are not able to determine variable's compile unit. if (cu_id == 0) continue; @@ -853,24 +853,16 @@ } std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) { - std::string decorated_name; - auto vm_addr = pdb_data.getVirtualAddress(); - if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) { -auto result_up = -m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol); -if (result_up) { - while (auto symbol_up = result_up->getNext()) { -if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) { - decorated_name = symbol_up->getRawSymbol().getName(); - break; -} - } -} - } - if (!decorated_name.empty()) -return decorated_name; + // Cache public names at first + if (m_public_names.empty()) +if (auto result_up = +m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol)) + while (auto symbol_up = result_up->getNext()) +if (auto addr = symbol_up->getRawSymbol().getVirtualAddress()) + m_public_names[addr] = symbol_up->getRawSymbol().getName(); - return std::string(); + // Look up the name in the cache + return m_public_names.lookup(pdb_data.getVirtualAddress()); } VariableSP SymbolFilePDB::ParseVariableForPDBData( @@ -1070,15 +1062,15 @@ sc.module_sp = m_obj_file->GetModule(); lldbassert(sc.module_sp.get()); -sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); -// FIXME: We are not able to determine the compile unit. -if (sc.comp_unit == nullptr) - continue; - if (!name.GetStringRef().equals( PDBASTParser::PDBNameDropScope(pdb_data->getName( continue; +sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); +// FIXME: We are not able to determine the compile unit. +if (sc.comp_unit == nullptr) + continue; + auto actual_parent_decl_ctx = GetDeclContextContainingUID(result->getSymIndexId()); if (actual_parent_decl_ctx != *parent_decl_ctx) @@ -1116,7 +1108,7 @@ sc.module_sp = m_obj_file->GetModule(); lldbassert(sc.module_sp.get()); -sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); +sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); // FIXME: We are not able to determine the compile unit. if (sc.comp_unit == nullptr) continue; @@ -1882,3 +1874,68 @@ return false; } + +uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) { + static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) { +return lhs < rhs.Offset; + }; + + // Cache section contributions + if (m_sec_contribs.empty()) { +if (auto SecContribs = m_session_up->getSectionContribs()) { + while (auto SectionContrib = SecContribs->getNext()) { +auto comp_id = Sec
[Lldb-commits] [PATCH] D53361: [API] Extend the `SBThreadPlan` interface
aleksandr.urakov added a comment. Ok, I'll do it, thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D53361 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. Ok, I'll reimplement this, thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53506: [ClangASTContext] Extract VTable pointers from C++ objects
aleksandr.urakov added a reviewer: zturner. aleksandr.urakov added a comment. In https://reviews.llvm.org/D53506#1270933, @zturner wrote: > So, the point is, just because we don't have access to the info via DIA > doesn't mean we won't have access to the info once the native pdb plugin is > complete. Just something to think about. Yes, I also try to see low-level PDB dumps now (since the case with FPO :) ), but in this case it seems that we still have no required info to retrieve VBase offsets. Consider the following example: struct A { int a = 1; }; struct B : virtual A { int b = 2; }; struct C : virtual A { int c = 3; }; struct D : virtual B, virtual C { int d = 4; }; int main() { D d{}; return 0; } Here for `D` we have the next `LF_FIELDLIST` (assume that the application is MSVC compiled): 0x1016 | LF_FIELDLIST [size = 96, hash = 0x415A] - LF_VBCLASS base = 0x1002, vbptr = 0x1004, vbptr offset = 0, vtable index = 2 attrs = public - LF_VBCLASS base = 0x1005, vbptr = 0x1004, vbptr offset = 0, vtable index = 3 attrs = public - LF_IVBCLASS base = 0x1006, vbptr = 0x1004, vbptr offset = 0, vtable index = 1 attrs = public - LF_MEMBER [name = `d`, Type = 0x0074 (int), offset = 4, attrs = public] - LF_METHOD [name = `D`, # overloads = 3, overload list = 0x1011] - LF_METHOD [name = `operator=`, # overloads = 2, overload list = 0x1015] 0x1017 | LF_STRUCTURE [size = 32, hash = 0xC4D] `D` unique name: `.?AUD@@` vtable: , base list: , field list: 0x1016 options: has ctor / dtor | has unique name | overloaded operator | overloaded operator=, sizeof 28 `vbptr offset` here is an offset to VBTable pointer, not to VBase. `MicrosoftRecordLayoutBuilder` requires exactly offsets to VBases as if they were non-virtual base classes. In general it is wrong, but it works ok if we know a real full type of the variable. `ClangASTContext` when retrieving a virtual base offset tries at first to retrieve it in the "fair" way: - retrieve the pointer to VTable; - read the offset to the VBase from VTable. If it fails somewhere, then it gets the VBase offset from the record layout. It is an "unfair" VBase offset, which was put there by `MicrosoftRecordLayoutBuilder`. And what I mean is that we have no info about it in PDB (to give it to `MicrosoftRecordLayoutBuilder`). What this patch makes is it allows the "fair" way to work in the case, when an object is already read from the debuggee. Then we will have `eAddressTypeHost` as an address type of `ValueObject`, and it used to lead to the situation when the "fair" way is failing and the "unfair" way is used. This patch allows to still process it by the "fair" way. To make things more clear consider the structures layout: class A size(4): +--- 0| a +--- class B size(12): +--- 0| {vbptr} 4| b +--- +--- (virtual base A) 8| a +--- class C size(12): +--- 0| {vbptr} 4| c +--- +--- (virtual base A) 8| a +--- class D size(28): +--- 0| {vbptr} 4| d +--- +--- (virtual base A) 8| a +--- +--- (virtual base B) 12| {vbptr} 16| b +--- +--- (virtual base C) 20| {vbptr} 24| c +--- `MicrosoftRecordsLayoutBuilder` waits that we will give it 8 as the VBase offset for `A` in `B`, `C` and `D`. In `D` for `B` it wants 12, and for `C` it wants 20. It's an info we are missing in PDB. Also this example can show how this patch should improve behavior on non-Windows too. If you will stand on `return 0` and call `print d`, then an invalid value should be printed for `A` inside `B` or `C`. If you call `frame variable d` then the value printed should be ok. It's because in the first case an object is already fully read from the debuggee, and without the patch the "unfair" way works, and it uses the offset to `A` from `B` (or `C`) as if `B` (or `C`) would be a real type of the variable (for the layout above it would use 8). But the real type is `D`, so offsets to `A` from `B` (or `C`) inside `D` are different (for the layout above it would be -4 from `B` and -12 from `C`). That's why "unfair" way doesn't work in this case. This patch should also fix it. Repository: rLLDB LLDB https://reviews.llvm.org/D53506 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53511: [NativePDB] Support type lookup by name
aleksandr.urakov accepted this revision. aleksandr.urakov added a comment. Looks good to me, thank you! https://reviews.llvm.org/D53511 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53361: [API] Extend the `SBThreadPlan` interface
aleksandr.urakov updated this revision to Diff 170852. aleksandr.urakov added a comment. I've added the test. Can you see, please, is it ok? https://reviews.llvm.org/D53361 Files: include/lldb/API/SBThreadPlan.h packages/Python/lldbsuite/test/functionalities/step_scripted/Makefile packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py packages/Python/lldbsuite/test/functionalities/step_scripted/main.c scripts/interface/SBThreadPlan.i source/API/SBThreadPlan.cpp Index: source/API/SBThreadPlan.cpp === --- source/API/SBThreadPlan.cpp +++ source/API/SBThreadPlan.cpp @@ -207,3 +207,13 @@ return SBThreadPlan(); } } + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) { + if (m_opaque_sp) { +return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( +false, script_class_name, false)); + } else { +return SBThreadPlan(); + } +} Index: scripts/interface/SBThreadPlan.i === --- scripts/interface/SBThreadPlan.i +++ scripts/interface/SBThreadPlan.i @@ -106,6 +106,9 @@ SBThreadPlan QueueThreadPlanForRunToAddress (SBAddress address); +SBThreadPlan +QueueThreadPlanForStepScripted(const char *script_class_name); + protected: friend class SBBreakpoint; Index: packages/Python/lldbsuite/test/functionalities/step_scripted/main.c === --- /dev/null +++ packages/Python/lldbsuite/test/functionalities/step_scripted/main.c @@ -0,0 +1,10 @@ +#include + +void foo() { + printf("Set a breakpoint here.\n"); +} + +int main() { + foo(); + return 0; +} Index: packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py === --- /dev/null +++ packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py @@ -0,0 +1,41 @@ +""" +Tests stepping with scripted thread plans. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class StepScriptedTestCase(TestBase): + +mydir = TestBase.compute_mydir(__file__) + +NO_DEBUG_INFO_TESTCASE = True + +def test_standard_step_out(self): +"""Tests stepping with the scripted thread plan laying over a standard thread plan for stepping out.""" +self.build() +self.main_source_file = lldb.SBFileSpec("main.c") +self.step_out_with_scripted_plan("Steps.StepOut") + +def test_scripted_step_out(self): +"""Tests stepping with the scripted thread plan laying over an another scripted thread plan for stepping out.""" +self.build() +self.main_source_file = lldb.SBFileSpec("main.c") +self.step_out_with_scripted_plan("Steps.StepScripted") + +def setUp(self): +TestBase.setUp(self) +self.runCmd("command script import Steps.py") + +def step_out_with_scripted_plan(self, name): +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) + +frame = thread.GetFrameAtIndex(0) +self.assertEqual("foo", frame.GetFunctionName()) + +err = thread.StepUsingScriptedThreadPlan(name) +self.assertTrue(err.Success(), "Failed to step out") + +frame = thread.GetFrameAtIndex(0) +self.assertEqual("main", frame.GetFunctionName()) Index: packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py === --- /dev/null +++ packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py @@ -0,0 +1,37 @@ +import lldb + +class StepWithChild: +def __init__(self, thread_plan): +self.thread_plan = thread_plan +self.child_thread_plan = self.queue_child_thread_plan() + +def explains_stop(self, event): +return False + +def should_stop(self, event): +if not self.child_thread_plan.IsPlanComplete(): +return False + +self.thread_plan.SetPlanComplete(True) + +return True + +def should_step(self): +return False + +def queue_child_thread_plan(self): +return None + +class StepOut(StepWithChild): +def __init__(self, thread_plan, dict): +StepWithChild.__init__(self, thread_plan) + +def queue_child_thread_plan(self): +return self.thread_plan.QueueThreadPlanForStepOut(0) + +class StepScripted(StepWithChild): +def __init__(self, thread_plan, dict): +StepWithChild.__init__(self, thread_plan) + +def queue_child_thread_plan(self): +return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut") Index: packages/Python/lldbsuite/test/functionalities/step_scripted/Makefi
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov updated this revision to Diff 170889. aleksandr.urakov added a comment. I've implemented things as Greg have said, except for a few moments: - haven't added `AddSymbols` to `SymbolVendor` because it is not used anywhere, and we can just use `SymbolFile::AddSymbols` directly inside of `SymbolVendor`; - have made `AddSymbols`' parameter as a reference instead of a pointer, because there is no reason to send null to this function; - have cached symtab in `SymbolVendor` to not pass it every time through the `SymbolFile::AddSymbols`. But if you don't agree with some of these I'm ready to discuss. https://reviews.llvm.org/D53368 Files: include/lldb/Symbol/SymbolFile.h include/lldb/Symbol/SymbolVendor.h include/lldb/lldb-forward.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h source/Symbol/SymbolVendor.cpp unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -616,3 +616,20 @@ EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared(fspec, aspec); + + SymbolContextList sc_list; + EXPECT_EQ(1u, +module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), + lldb::eSymbolTypeAny, sc_list)); + EXPECT_EQ(1u, sc_list.GetSize()); + + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_STREQ("int foo(int)", + sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); +} Index: source/Symbol/SymbolVendor.cpp === --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -61,7 +61,7 @@ //-- SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) : ModuleChild(module_sp), m_type_list(), m_compile_units(), - m_sym_file_ap() {} + m_sym_file_ap(), m_symtab() {} //-- // Destructor @@ -438,14 +438,23 @@ Symtab *SymbolVendor::GetSymtab() { ModuleSP module_sp(GetModule()); - if (module_sp) { -ObjectFile *objfile = module_sp->GetObjectFile(); -if (objfile) { - // Get symbol table from unified section list. - return objfile->GetSymtab(); -} - } - return nullptr; + if (!module_sp) +return nullptr; + + std::lock_guard guard(module_sp->GetMutex()); + + if (m_symtab) +return m_symtab; + + ObjectFile *objfile = module_sp->GetObjectFile(); + if (!objfile) +return nullptr; + + m_symtab = objfile->GetSymtab(); + if (m_symtab && m_sym_file_ap) +m_sym_file_ap->AddSymbols(*m_symtab); + + return m_symtab; } void SymbolVendor::ClearSymtab() { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -132,6 +132,8 @@ const std::string &scope_qualified_name, std::vector &mangled_names) override; + void AddSymbols(lldb_private::Symtab &symtab) override; + uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, @@ -236,9 +238,13 @@ uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); + lldb_private::Symbol * + GetPublicSymbol(const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_symbols; llvm::DenseMap m_public_names; SecContribsMap m_sec_contribs; Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1331,6 +1331,31 @@ const std::string &scope_qualified_name, std::vector &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { + std::set sym_addresses; + for (size_t i = 0; i < symtab.GetNumSymbols(); i++) +sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); + + auto results = m_global_scope_up->findAllChildren(); + if (!results) +return; + + while (auto pub_symbol = results->getNext()) { +auto symbol_ptr = GetPublicSymbol(*pub_symbol); +if (!symbol_ptr) + continue; + +auto file_addr = symbol_ptr->GetFileAddress(); +if (sym_addresses.find(file_addr) != sym_addresses.end()) + continue; +sym_add
[Lldb-commits] [PATCH] D53361: [API] Extend the `SBThreadPlan` interface
This revision was automatically updated to reflect the committed changes. Closed by commit rL345247: [API] Extend the `SBThreadPlan` interface (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53361?vs=170852&id=171048#toc Repository: rL LLVM https://reviews.llvm.org/D53361 Files: lldb/trunk/include/lldb/API/SBThreadPlan.h lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c lldb/trunk/scripts/interface/SBThreadPlan.i lldb/trunk/source/API/SBThreadPlan.cpp Index: lldb/trunk/scripts/interface/SBThreadPlan.i === --- lldb/trunk/scripts/interface/SBThreadPlan.i +++ lldb/trunk/scripts/interface/SBThreadPlan.i @@ -106,6 +106,9 @@ SBThreadPlan QueueThreadPlanForRunToAddress (SBAddress address); +SBThreadPlan +QueueThreadPlanForStepScripted(const char *script_class_name); + protected: friend class SBBreakpoint; Index: lldb/trunk/include/lldb/API/SBThreadPlan.h === --- lldb/trunk/include/lldb/API/SBThreadPlan.h +++ lldb/trunk/include/lldb/API/SBThreadPlan.h @@ -88,6 +88,8 @@ SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address); + SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name); + #ifndef SWIG lldb_private::ThreadPlan *get(); #endif Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c === --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c @@ -0,0 +1,10 @@ +#include + +void foo() { + printf("Set a breakpoint here.\n"); +} + +int main() { + foo(); + return 0; +} Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py === --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py @@ -0,0 +1,37 @@ +import lldb + +class StepWithChild: +def __init__(self, thread_plan): +self.thread_plan = thread_plan +self.child_thread_plan = self.queue_child_thread_plan() + +def explains_stop(self, event): +return False + +def should_stop(self, event): +if not self.child_thread_plan.IsPlanComplete(): +return False + +self.thread_plan.SetPlanComplete(True) + +return True + +def should_step(self): +return False + +def queue_child_thread_plan(self): +return None + +class StepOut(StepWithChild): +def __init__(self, thread_plan, dict): +StepWithChild.__init__(self, thread_plan) + +def queue_child_thread_plan(self): +return self.thread_plan.QueueThreadPlanForStepOut(0) + +class StepScripted(StepWithChild): +def __init__(self, thread_plan, dict): +StepWithChild.__init__(self, thread_plan) + +def queue_child_thread_plan(self): +return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut") Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py === --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py @@ -0,0 +1,41 @@ +""" +Tests stepping with scripted thread plans. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class StepScriptedTestCase(TestBase): + +mydir = TestBase.compute_mydir(__file__) + +NO_DEBUG_INFO_TESTCASE = True + +def test_standard_step_out(self): +"""Tests stepping with the scripted thread plan laying over a standard thread plan for stepping out.""" +self.build() +self.main_source_file = lldb.SBFileSpec("main.c") +self.step_out_with_scripted_plan("Steps.StepOut") + +def test_scripted_step_out(self): +"""Tests stepping with the scripted thread plan laying over an another scripted thread plan for stepping out.""" +self.build() +self.main_source_file = lldb.SBFileSpec("main.c") +self.step_out_with_scripted_plan("Steps.StepScripted") + +def setUp(self): +TestBase.setUp(self) +self.runCmd("command script import Steps.py") + +def step_out_with_scripted_plan(self, name): +(t
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov marked 5 inline comments as done. aleksandr.urakov added a comment. Ah, yes, sure! It's my mistake. I didn't pay attention to the fact that a symtab owns symbols. I'll update the patch, thanks! Comment at: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp:1344-1346 +auto symbol_ptr = GetPublicSymbol(*pub_symbol); +if (!symbol_ptr) + continue; clayborg wrote: > Maybe get the file address from "pub_symbol" and avoid converting to a > SymbolSP that we will never use? See more comments below. Unfortunately there is no method of `PDBSymbolPublicSymbol` which allows to retrieve the file address directly. I'll calculate it as section + offset instead. Comment at: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp:1353 + +symtab.AddSymbol(*symbol_ptr); + } clayborg wrote: > Just make a local symbol and convert it from PDB to lldb_private::Symbol > here? Something like: > ``` > symtab.AddSymbol(ConvertPDBSymbol(pdb_symbol)); > ``` > > So it seems we shouldn't need the m_public_symbols storage in this class > anymore since "symtab" will now own the symbol we just created. The problem here is that `ConvertPDBSymbol` can fail e.g. if somehow `pub_symbol` will contain an invalid section number. We can: - change the interface of the function to signal about errors; - just assume that the section number is always valid (because we already retrieved it before during the file address calculation). In both cases we will retrieve the section twice. We also can: - just pass already calculated section and offset to `ConvertPDBSymbol`. But it leads to a blurred responsibility and a weird interface. So I think that it would be better just create a symbol right here - it seems that it doesn't make the code more complex. What do you think about it? Comment at: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp:1968-1969 + +lldb_private::Symbol *SymbolFilePDB::GetPublicSymbol( +const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol) { + auto it = m_public_symbols.find(pub_symbol.getSymIndexId()); clayborg wrote: > Maybe convert this to: > ``` > lldb_private::Symbol ConvertPDBSymbol(const llvm::pdb::PDBSymbolPublicSymbol > &pub_symbol) > ``` > And we only call this if we need to create a symbol we will add to the > "symtab" in SymbolFilePDB::AddSymbols(...) See the comment above https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov updated this revision to Diff 171056. aleksandr.urakov marked 3 inline comments as done. https://reviews.llvm.org/D53368 Files: include/lldb/Symbol/SymbolFile.h include/lldb/Symbol/SymbolVendor.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h source/Symbol/SymbolVendor.cpp unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -616,3 +616,20 @@ EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared(fspec, aspec); + + SymbolContextList sc_list; + EXPECT_EQ(1u, +module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), + lldb::eSymbolTypeAny, sc_list)); + EXPECT_EQ(1u, sc_list.GetSize()); + + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_STREQ("int foo(int)", + sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); +} Index: source/Symbol/SymbolVendor.cpp === --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -61,7 +61,7 @@ //-- SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) : ModuleChild(module_sp), m_type_list(), m_compile_units(), - m_sym_file_ap() {} + m_sym_file_ap(), m_symtab() {} //-- // Destructor @@ -438,14 +438,23 @@ Symtab *SymbolVendor::GetSymtab() { ModuleSP module_sp(GetModule()); - if (module_sp) { -ObjectFile *objfile = module_sp->GetObjectFile(); -if (objfile) { - // Get symbol table from unified section list. - return objfile->GetSymtab(); -} - } - return nullptr; + if (!module_sp) +return nullptr; + + std::lock_guard guard(module_sp->GetMutex()); + + if (m_symtab) +return m_symtab; + + ObjectFile *objfile = module_sp->GetObjectFile(); + if (!objfile) +return nullptr; + + m_symtab = objfile->GetSymtab(); + if (m_symtab && m_sym_file_ap) +m_sym_file_ap->AddSymbols(*m_symtab); + + return m_symtab; } void SymbolVendor::ClearSymtab() { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -132,6 +132,8 @@ const std::string &scope_qualified_name, std::vector &mangled_names) override; + void AddSymbols(lldb_private::Symtab &symtab) override; + uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1331,6 +1331,58 @@ const std::string &scope_qualified_name, std::vector &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { + std::set sym_addresses; + for (size_t i = 0; i < symtab.GetNumSymbols(); i++) +sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); + + auto results = m_global_scope_up->findAllChildren(); + if (!results) +return; + + auto section_list = m_obj_file->GetSectionList(); + if (!section_list) +return; + + while (auto pub_symbol = results->getNext()) { +auto section_idx = pub_symbol->getAddressSection() - 1; +if (section_idx >= section_list->GetSize()) + continue; + +auto section = section_list->GetSectionAtIndex(section_idx); +if (!section) + continue; + +auto offset = pub_symbol->getAddressOffset(); + +auto file_addr = section->GetFileAddress() + offset; +if (sym_addresses.find(file_addr) != sym_addresses.end()) + continue; +sym_addresses.insert(file_addr); + +auto size = pub_symbol->getLength(); +symtab.AddSymbol( +Symbol(pub_symbol->getSymIndexId(), // symID + pub_symbol->getName().c_str(), // name + true, // name_is_mangled + pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type + true, // external + false, // is_debug + false, // is_trampoline + false, // is_artificial + section, // section_sp + offset,// value + size, // size +
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. Yes, I'll implement it tomorrow (I'm already OOO now), thanks. But is it really necessary to check the number of symbols added if we must to calculate / finalize the symtab after getting it from object file anyway? May be just always do it after creation and processing by the symbol file? For each symtab it will be done just once because of caching. https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov updated this revision to Diff 171267. aleksandr.urakov added a comment. Herald added subscribers: arichardson, emaste. Herald added a reviewer: espindola. That's done! https://reviews.llvm.org/D53368 Files: include/lldb/Symbol/SymbolFile.h include/lldb/Symbol/SymbolVendor.h source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h source/Symbol/SymbolVendor.cpp unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -616,3 +616,20 @@ EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared(fspec, aspec); + + SymbolContextList sc_list; + EXPECT_EQ(1u, +module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), + lldb::eSymbolTypeAny, sc_list)); + EXPECT_EQ(1u, sc_list.GetSize()); + + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_STREQ("int foo(int)", + sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); +} Index: source/Symbol/SymbolVendor.cpp === --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -61,7 +61,7 @@ //-- SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) : ModuleChild(module_sp), m_type_list(), m_compile_units(), - m_sym_file_ap() {} + m_sym_file_ap(), m_symtab() {} //-- // Destructor @@ -438,14 +438,26 @@ Symtab *SymbolVendor::GetSymtab() { ModuleSP module_sp(GetModule()); - if (module_sp) { -ObjectFile *objfile = module_sp->GetObjectFile(); -if (objfile) { - // Get symbol table from unified section list. - return objfile->GetSymtab(); -} - } - return nullptr; + if (!module_sp) +return nullptr; + + std::lock_guard guard(module_sp->GetMutex()); + + if (m_symtab) +return m_symtab; + + ObjectFile *objfile = module_sp->GetObjectFile(); + if (!objfile) +return nullptr; + + m_symtab = objfile->GetSymtab(); + if (m_symtab && m_sym_file_ap) +m_sym_file_ap->AddSymbols(*m_symtab); + + m_symtab->CalculateSymbolSizes(); + m_symtab->Finalize(); + + return m_symtab; } void SymbolVendor::ClearSymtab() { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -133,6 +133,8 @@ const std::string &scope_qualified_name, std::vector &mangled_names) override; + void AddSymbols(lldb_private::Symtab &symtab) override; + uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1331,6 +1331,55 @@ const std::string &scope_qualified_name, std::vector &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { + std::set sym_addresses; + for (size_t i = 0; i < symtab.GetNumSymbols(); i++) +sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); + + auto results = m_global_scope_up->findAllChildren(); + if (!results) +return; + + auto section_list = m_obj_file->GetSectionList(); + if (!section_list) +return; + + while (auto pub_symbol = results->getNext()) { +auto section_idx = pub_symbol->getAddressSection() - 1; +if (section_idx >= section_list->GetSize()) + continue; + +auto section = section_list->GetSectionAtIndex(section_idx); +if (!section) + continue; + +auto offset = pub_symbol->getAddressOffset(); + +auto file_addr = section->GetFileAddress() + offset; +if (sym_addresses.find(file_addr) != sym_addresses.end()) + continue; +sym_addresses.insert(file_addr); + +auto size = pub_symbol->getLength(); +symtab.AddSymbol( +Symbol(pub_symbol->getSymIndexId(), // symID + pub_symbol->getName().c_str(), // name + true, // name_is_mangled + pub_
[Lldb-commits] [PATCH] D53749: [PDB] Fix `SymbolFilePDBTests` after r345313
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, stella.stamenova. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits. This one fixes tests compilation preserving the type of the `scope` parameter. Repository: rLLDB LLDB https://reviews.llvm.org/D53749 Files: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -270,7 +270,7 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + auto scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; uint32_t count = symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list); @@ -319,7 +319,7 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + auto scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; // First test with line 7, and verify that only line 7 entries are added. uint32_t count = Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -270,7 +270,7 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + auto scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; uint32_t count = symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list); @@ -319,7 +319,7 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + auto scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; // First test with line 7, and verify that only line 7 entries are added. uint32_t count = ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53749: [PDB] Fix `SymbolFilePDBTests` after r345313
aleksandr.urakov added a comment. Ok, thanks! I didn't know about such rule. I'll reduce usages of auto :) As for such an obvious changes, is it ok to commit them without a review? Or is it still preferable to create reviews for them? Repository: rLLDB LLDB https://reviews.llvm.org/D53749 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53749: [PDB] Fix `SymbolFilePDBTests` after r345313
aleksandr.urakov added a comment. Ok, good! Repository: rLLDB LLDB https://reviews.llvm.org/D53749 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53749: [PDB] Fix `SymbolFilePDBTests` after r345313
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rLLDB345374: [PDB] Fix `SymbolFilePDBTests` after r345313 (authored by aleksandr.urakov, committed by ). Changed prior to commit: https://reviews.llvm.org/D53749?vs=171269&id=171275#toc Repository: rLLDB LLDB https://reviews.llvm.org/D53749 Files: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -270,7 +270,8 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + lldb::SymbolContextItem scope = + lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; uint32_t count = symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list); @@ -319,7 +320,8 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + lldb::SymbolContextItem scope = + lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; // First test with line 7, and verify that only line 7 entries are added. uint32_t count = Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -270,7 +270,8 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + lldb::SymbolContextItem scope = + lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; uint32_t count = symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list); @@ -319,7 +320,8 @@ EXPECT_EQ(2u, cus); SymbolContextList sc_list; - uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + lldb::SymbolContextItem scope = + lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; // First test with line 7, and verify that only line 7 entries are added. uint32_t count = ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53753: [Windows] Define generic arguments registers for Windows x64
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, stella.stamenova, labath. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits. When evaluating expressions the generic arguments registers are required by ABI. This patch defines them. Repository: rLLDB LLDB https://reviews.llvm.org/D53753 Files: source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp Index: source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp === --- source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -74,12 +74,12 @@ nullptr, nullptr}, {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, nullptr, nullptr}, {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, nullptr, nullptr}, @@ -104,22 +104,22 @@ nullptr, nullptr}, {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, nullptr, nullptr}, Index: source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp === --- source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -74,12 +74,12 @@ nullptr, nullptr}, {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, nullptr, nullptr}, {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, nullptr, nullptr}, @@ -104,22 +104,22 @@ nullptr, nullptr}, {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, nullptr, nullptr}, ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53759: [PDB] Support PDB-backed expressions evaluation
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, asmith, stella.stamenova. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor, JDevlieghere, aprantl. This patch contains several small fixes, which makes it possible to evaluate expressions on Windows using information from PDB. The changes are: - several sanitize checks; - make `IRExecutionUnit::MemoryManager::getSymbolAddress` to not return a magic value on a failure, because callers wait 0 in this case; - entry point required to be a file address, not RVA, in the `ObjectFilePECOFF`; - do not crash on a debuggee second chance exception - it may be an expression evaluation crash; - create parameter declarations for functions in AST to make it possible to call debugee functions from expressions; - relax name searching rules for variables, functions, namespaces and types. Now it works just like in the DWARF plugin; - fix endless recursion in `SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc`. Each change is small and it is hard to test each change separately, so I think that create one review for them all is not a bad idea, especially because they make together the test to work. I remember about the new native PDB plugin, but these changes are old enough, for last two or three weeks I'm just releasing my stash :) And some of the changes may be useful for the new plugin too. This review depends on https://reviews.llvm.org/D52461, https://reviews.llvm.org/D52618, https://reviews.llvm.org/D53368, x64 testing depends on https://reviews.llvm.org/D53753. Repository: rLLDB LLDB https://reviews.llvm.org/D53759 Files: lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script lit/SymbolFile/PDB/expressions.test source/Core/RichManglingContext.cpp source/Expression/IRExecutionUnit.cpp source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp source/Plugins/Process/Windows/Common/ProcessWindows.cpp source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -286,6 +286,10 @@ const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) { lldbassert(sc.comp_unit && sc.module_sp.get()); + if (FunctionSP result = + sc.comp_unit->FindFunctionByUID(pdb_func.getSymIndexId())) +return result.get(); + auto file_vm_addr = pdb_func.getVirtualAddress(); if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) return nullptr; @@ -1042,8 +1046,6 @@ const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) { - if (!parent_decl_ctx) -parent_decl_ctx = m_tu_decl_ctx_up.get(); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return 0; if (name.IsEmpty()) @@ -1073,9 +1075,8 @@ if (sc.comp_unit == nullptr) continue; -auto actual_parent_decl_ctx = -GetDeclContextContainingUID(result->getSymIndexId()); -if (actual_parent_decl_ctx != *parent_decl_ctx) +if (parent_decl_ctx && GetDeclContextContainingUID( + result->getSymIndexId()) != *parent_decl_ctx) continue; ParseVariables(sc, *pdb_data, &variables); @@ -1266,20 +1267,28 @@ CacheFunctionNames(); std::set resolved_ids; -auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids, - this](UniqueCStringMap &Names) { +auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list, + &resolved_ids](UniqueCStringMap &Names) { std::vector ids; - if (Names.GetValues(name, ids)) { -for (auto id : ids) { - if (resolved_ids.find(id) == resolved_ids.end()) { -if (ResolveFunction(id, include_inlines, sc_list)) - resolved_ids.insert(id); - } -} + if (!Names.GetValues(name, ids)) +return; + + for (uint32_t id : ids) { +if (resolved_ids.find(id) != resolved_ids.end()) + continue; + +if (parent_decl_ctx && +GetDeclContextContainingUID(id) != *parent_decl_ctx) + continue; + +if (ResolveFunction(id, include_inlines, sc_list)) + resolved_ids.insert(id); } }; if (name_type_mask & eFunctionNameTypeFull) { ResolveFn(m_func_full_names); + ResolveFn(m_func_base_names); + ResolveFn(m_func_method_names); } if (name_ty
[Lldb-commits] [PATCH] D53761: [Target] Do not skip a stop on a breakpoint if a plan was completed
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: jingham, zturner, boris.ulasevich. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor. This patch fixes the next situation. On Windows `clang-cl` makes no stub before the `main` function, so the `main` function is located exactly on module entry point. May be it is the same on other platforms. So consider the following sequence: - set a breakpoint on `main` and stop there; - try to evaluate expression, which requires a code execution on the debuggee side. Such an execution always returns to the module entry, and the plan waits for it there; - the plan understands that it is complete now and removes its breakpoint. But the breakpoint site is still there, because we also have a breakpoint on entry; - `StopInfo` analyzes a situation. It sees that we have stopped on the breakpoint site, and it sees that the breakpoint site has owners, and no one logical breakpoint is internal (because the plan is already completed and it have removed its breakpoint); - `StopInfo` thinks that it's a user breakpoint and skips it to avoid recursive computations; - the program continues. So in this situation the program continues without a stop right after the expression evaluation. To avoid this I've added an additional check that the plan was completed. The test is just the case I've caught, but it's Windows-only. It seems that the problem should exist on other platforms too, but I don't know how to test it in a cross-platform way (any tips are appreciated). The test depends on https://reviews.llvm.org/D53759. Repository: rLLDB LLDB https://reviews.llvm.org/D53761 Files: lit/SymbolFile/PDB/Inputs/BPOnEntryTest.cpp lit/SymbolFile/PDB/Inputs/BPOnEntryTest.script lit/SymbolFile/PDB/bp-on-entry.test source/Target/StopInfo.cpp Index: source/Target/StopInfo.cpp === --- source/Target/StopInfo.cpp +++ source/Target/StopInfo.cpp @@ -333,6 +333,13 @@ // commands when we see the same breakpoint hit a second time. m_should_stop_is_valid = true; + +if (thread_sp->CompletedPlanOverridesBreakpoint()) { + m_should_stop = true; + thread_sp->ResetStopInfo(); + return; +} + if (log) log->Printf("StopInfoBreakpoint::PerformAction - Hit a " "breakpoint while running an expression," Index: lit/SymbolFile/PDB/bp-on-entry.test === --- /dev/null +++ lit/SymbolFile/PDB/bp-on-entry.test @@ -0,0 +1,7 @@ +REQUIRES: windows +RUN: clang-cl /Zi /GS- /c %S/Inputs/BPOnEntryTest.cpp /Fo%t.obj +RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe +RUN: %lldb -b -s %S/Inputs/BPOnEntryTest.script -- %t.exe | FileCheck %s + +CHECK: (lldb) print sum(3, 4) +CHECK: (int) $0 = 7 Index: lit/SymbolFile/PDB/Inputs/BPOnEntryTest.script === --- /dev/null +++ lit/SymbolFile/PDB/Inputs/BPOnEntryTest.script @@ -0,0 +1,3 @@ +breakpoint set --file BPOnEntryTest.cpp --name main +run +print sum(3, 4) Index: lit/SymbolFile/PDB/Inputs/BPOnEntryTest.cpp === --- /dev/null +++ lit/SymbolFile/PDB/Inputs/BPOnEntryTest.cpp @@ -0,0 +1,7 @@ +int sum(int a, int b) { + return a + b; +} + +int main() { + return sum(-1, 1); +} Index: source/Target/StopInfo.cpp === --- source/Target/StopInfo.cpp +++ source/Target/StopInfo.cpp @@ -333,6 +333,13 @@ // commands when we see the same breakpoint hit a second time. m_should_stop_is_valid = true; + +if (thread_sp->CompletedPlanOverridesBreakpoint()) { + m_should_stop = true; + thread_sp->ResetStopInfo(); + return; +} + if (log) log->Printf("StopInfoBreakpoint::PerformAction - Hit a " "breakpoint while running an expression," Index: lit/SymbolFile/PDB/bp-on-entry.test === --- /dev/null +++ lit/SymbolFile/PDB/bp-on-entry.test @@ -0,0 +1,7 @@ +REQUIRES: windows +RUN: clang-cl /Zi /GS- /c %S/Inputs/BPOnEntryTest.cpp /Fo%t.obj +RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe +RUN: %lldb -b -s %S/Inputs/BPOnEntryTest.script -- %t.exe | FileCheck %s + +CHECK: (lldb) print sum(3, 4) +CHECK: (int) $0 = 7 Index: lit/SymbolFile/PDB/Inputs/BPOnEntryTest.script === --- /dev/null +++ lit/SymbolFile/PDB/Inputs/BPOnEntryTest.script @@ -0,0 +1,3 @@ +breakpoint set --file BPOnEntryTest.cpp --name main +run +print sum(3, 4) Index: lit/SymbolFile/PDB/Inputs/BP
[Lldb-commits] [PATCH] D53753: [Windows] Define generic arguments registers for Windows x64
aleksandr.urakov added a comment. Thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D53753 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53753: [Windows] Define generic arguments registers for Windows x64
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL345385: [Windows] Define generic arguments registers for Windows x64 (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53753?vs=171281&id=171299#toc Repository: rL LLVM https://reviews.llvm.org/D53753 Files: lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp Index: lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp === --- lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -74,12 +74,12 @@ nullptr, nullptr}, {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, nullptr, nullptr}, {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, nullptr, nullptr}, @@ -104,22 +104,22 @@ nullptr, nullptr}, {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, nullptr, nullptr}, Index: lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp === --- lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -74,12 +74,12 @@ nullptr, nullptr}, {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, nullptr, nullptr}, {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, nullptr, nullptr}, @@ -104,22 +104,22 @@ nullptr, nullptr}, {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, nullptr, nullptr}, ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52618: [Windows] A basic implementation of memory allocations in a debuggee process
aleksandr.urakov added a comment. In https://reviews.llvm.org/D52618#1278442, @zturner wrote: > Is this still blocked on anything? It seems that it's not blocked on anything. The test, as you have mentioned in the earlier message, is already duplicating only `RUN: lldb-test` lines, there are no check files used here. Comment at: source/Plugins/Process/Windows/Common/ProcessWindows.cpp:712 +lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) { Hui wrote: > Looks to me they are handlers to the GDB remote "__m" and "__M" packets. If > the remote is on Windows host, the debug inferior shall be responsible to > handle memory allocation/deallocation for JITed codes. (There is a process > utility for InferiorCall). Otherwise, the requests will be answered by > remote gdb server with memory region returned. No, they are not, it's not an lldb-server plugin, it's a native Windows process plugin. https://reviews.llvm.org/D52618 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53759: [PDB] Support PDB-backed expressions evaluation
aleksandr.urakov marked 2 inline comments as done. aleksandr.urakov added inline comments. Comment at: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp:819 if (!section_list) m_entry_point_address.SetOffset(offset); else Hui wrote: > This still needs to be the offset into the section. If we are here, then we can't retrieve a section list, then we can't specify a section offset here. Setting an offset without setting a section means that offset must be treated as a file address (see e.g. the implementation of the `Address::GetFileAddress()` function). I think that misleading here is the name of the variable `offset`, I'll fix it, thanks. Comment at: source/Plugins/Process/Windows/Common/ProcessWindows.cpp:959 +// It may be an expression evaluation crash. +SetPrivateState(eStateStopped); } stella.stamenova wrote: > Are we going to determine later whether it is supposed to be a crash or just > never crash on second chance exceptions? Yes, it's a good question... I can't understand how to figure out at this point if the exception was thrown during an expression evaluation or a debuggee execution. On other hand, it seems that Visual Studio also doesn't crash an application in such situations: ``` int main() { char *buf = nullptr; buf[0] = 0; // Unhandled exception is here, but you can safely continue an execution if you will drag an arrow on the next line in Visual Studio int x = 5; return x - 5; } ``` Also it was the only place where `eStateCrashed` was set, so it seems that on other platforms we do not crash a debuggee in such situations too. So may be it's not a bad idea to not set the crashed state here at all. But if someone don't agree with me and has an idea how to do it better, I'm ready to fix it. Comment at: source/Plugins/SymbolFile/PDB/PDBASTParser.cpp:1085 + } else +set = &m_namespaces; + assert(set); stella.stamenova wrote: > Nit: Maybe add curly braces here. Since the if statement has them, the code > is easier to read if the else does as well. Sure, thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D53759 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53759: [PDB] Support PDB-backed expressions evaluation
aleksandr.urakov updated this revision to Diff 171489. aleksandr.urakov marked 2 inline comments as done. aleksandr.urakov added a comment. Update the diff according to comments. https://reviews.llvm.org/D53759 Files: lit/SymbolFile/PDB/Inputs/ExpressionsTest.cpp lit/SymbolFile/PDB/Inputs/ExpressionsTest0.script lit/SymbolFile/PDB/Inputs/ExpressionsTest1.script lit/SymbolFile/PDB/Inputs/ExpressionsTest2.script lit/SymbolFile/PDB/expressions.test source/Core/RichManglingContext.cpp source/Expression/IRExecutionUnit.cpp source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp source/Plugins/Process/Windows/Common/ProcessWindows.cpp source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -286,6 +286,10 @@ const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) { lldbassert(sc.comp_unit && sc.module_sp.get()); + if (FunctionSP result = + sc.comp_unit->FindFunctionByUID(pdb_func.getSymIndexId())) +return result.get(); + auto file_vm_addr = pdb_func.getVirtualAddress(); if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) return nullptr; @@ -1042,8 +1046,6 @@ const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) { - if (!parent_decl_ctx) -parent_decl_ctx = m_tu_decl_ctx_up.get(); if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return 0; if (name.IsEmpty()) @@ -1073,9 +1075,8 @@ if (sc.comp_unit == nullptr) continue; -auto actual_parent_decl_ctx = -GetDeclContextContainingUID(result->getSymIndexId()); -if (actual_parent_decl_ctx != *parent_decl_ctx) +if (parent_decl_ctx && GetDeclContextContainingUID( + result->getSymIndexId()) != *parent_decl_ctx) continue; ParseVariables(sc, *pdb_data, &variables); @@ -1266,20 +1267,28 @@ CacheFunctionNames(); std::set resolved_ids; -auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids, - this](UniqueCStringMap &Names) { +auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list, + &resolved_ids](UniqueCStringMap &Names) { std::vector ids; - if (Names.GetValues(name, ids)) { -for (auto id : ids) { - if (resolved_ids.find(id) == resolved_ids.end()) { -if (ResolveFunction(id, include_inlines, sc_list)) - resolved_ids.insert(id); - } -} + if (!Names.GetValues(name, ids)) +return; + + for (uint32_t id : ids) { +if (resolved_ids.find(id) != resolved_ids.end()) + continue; + +if (parent_decl_ctx && +GetDeclContextContainingUID(id) != *parent_decl_ctx) + continue; + +if (ResolveFunction(id, include_inlines, sc_list)) + resolved_ids.insert(id); } }; if (name_type_mask & eFunctionNameTypeFull) { ResolveFn(m_func_full_names); + ResolveFn(m_func_base_names); + ResolveFn(m_func_method_names); } if (name_type_mask & eFunctionNameTypeBase) { ResolveFn(m_func_base_names); @@ -1458,8 +1467,6 @@ const std::string &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types) { - if (!parent_decl_ctx) -parent_decl_ctx = m_tu_decl_ctx_up.get(); std::unique_ptr results; if (name.empty()) return; @@ -1492,9 +1499,8 @@ if (!ResolveTypeUID(result->getSymIndexId())) continue; -auto actual_parent_decl_ctx = -GetDeclContextContainingUID(result->getSymIndexId()); -if (actual_parent_decl_ctx != *parent_decl_ctx) +if (parent_decl_ctx && GetDeclContextContainingUID( + result->getSymIndexId()) != *parent_decl_ctx) continue; auto iter = m_types.find(result->getSymIndexId()); Index: source/Plugins/SymbolFile/PDB/PDBASTParser.h === --- source/Plugins/SymbolFile/PDB/PDBASTParser.h +++ source/Plugins/SymbolFile/PDB/PDBASTParser.h @@ -69,7 +69,8 @@ typedef llvm::DenseMap CXXRecordDeclToUidMap; typedef llvm::DenseMap UidToDeclMap; - typedef llvm::DenseMap> + typedef std::set NamespacesSet; + typedef llvm::DenseMap ParentToNamespacesMap; typedef llvm::DenseMap DeclContextToUidMap; @@ -109,6 +110,7 @@ CXXRecordDeclToUidMap m_forward_decl_to_uid; UidToDeclMap m_uid_to_decl; ParentToNamespaces
[Lldb-commits] [PATCH] D53761: [Target] Do not skip a stop on a breakpoint if a plan was completed
aleksandr.urakov updated this revision to Diff 171496. aleksandr.urakov added a comment. Thanks! I've updated the diff according to comments. https://reviews.llvm.org/D53761 Files: include/lldb/API/SBModule.h packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c scripts/interface/SBModule.i source/API/SBModule.cpp source/Target/StopInfo.cpp Index: source/Target/StopInfo.cpp === --- source/Target/StopInfo.cpp +++ source/Target/StopInfo.cpp @@ -333,6 +333,19 @@ // commands when we see the same breakpoint hit a second time. m_should_stop_is_valid = true; + +// It is possible that the user has a breakpoint at the same site +// as the completed plan had (e.g. user has a breakpoint +// on a module entry point, and `ThreadPlanCallFunction` ends +// also there). We can't find an internal breakpoint in the loop +// later because it was already removed on the plan completion. +// So check if the plan was completed, and stop if so. +if (thread_sp->CompletedPlanOverridesBreakpoint()) { + m_should_stop = true; + thread_sp->ResetStopInfo(); + return; +} + if (log) log->Printf("StopInfoBreakpoint::PerformAction - Hit a " "breakpoint while running an expression," Index: source/API/SBModule.cpp === --- source/API/SBModule.cpp +++ source/API/SBModule.cpp @@ -591,3 +591,14 @@ } return sb_addr; } + +lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const { + lldb::SBAddress sb_addr; + ModuleSP module_sp(GetSP()); + if (module_sp) { +ObjectFile *objfile_ptr = module_sp->GetObjectFile(); +if (objfile_ptr) + sb_addr.ref() = objfile_ptr->GetEntryPointAddress(); + } + return sb_addr; +} Index: scripts/interface/SBModule.i === --- scripts/interface/SBModule.i +++ scripts/interface/SBModule.i @@ -332,6 +332,9 @@ lldb::SBAddress GetObjectFileHeaderAddress() const; +lldb::SBAddress +GetObjectFileEntryPointAddress() const; + bool operator == (const lldb::SBModule &rhs) const; Index: packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c === --- /dev/null +++ packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c @@ -0,0 +1,10 @@ +#include + +int sum(int x, int y) { + return x + y; +} + +int main() { + printf("Set a breakpoint here.\n"); + return sum(-1, 1); +} Index: packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py === --- /dev/null +++ packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py @@ -0,0 +1,34 @@ +""" +Tests expressions evaluation when the breakpoint on module's entry is set. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprEntryBPTestCase(TestBase): + +mydir = TestBase.compute_mydir(__file__) + +NO_DEBUG_INFO_TESTCASE = True + +def test_expr_entry_bp(self): +"""Tests expressions evaluation when the breakpoint on module's entry is set.""" +self.build() +self.main_source_file = lldb.SBFileSpec("main.c") + +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) + +self.assertEqual(1, bkpt.GetNumLocations()) +entry = bkpt.GetLocationAtIndex(0).GetAddress().GetModule().GetObjectFileEntryPointAddress() +self.assertTrue(entry.IsValid(), "Can't get a module entry point") + +entry_bp = target.BreakpointCreateBySBAddress(entry) +self.assertTrue(entry_bp.IsValid(), "Can't set a breakpoint on the module entry point") + +result = target.EvaluateExpression("sum(7, 1)") +self.assertTrue(result.IsValid(), "Can't evaluate expression") +self.assertEqual(8, result.GetValueAsSigned()) + +def setUp(self): +TestBase.setUp(self) Index: packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile === --- /dev/null +++ packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Index: include/lldb/API/SBModule.h === --- include/lldb/API/SBModule.h +++ include/lldb/API/SBModule.h @@ -309,6 +309
[Lldb-commits] [PATCH] D53435: [x86] Fix issues with a realigned stack in MSVC compiled applications
aleksandr.urakov added a comment. Ping! Can you look at this, please? Repository: rLLDB LLDB https://reviews.llvm.org/D53435 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53761: [Target] Do not skip a stop on a breakpoint if a plan was completed
aleksandr.urakov added a comment. Thank you! https://reviews.llvm.org/D53761 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53435: [x86] Fix issues with a realigned stack in MSVC compiled applications
aleksandr.urakov marked 2 inline comments as done. aleksandr.urakov added a comment. Thank you! I'll update the patch. Comment at: source/Plugins/Process/Utility/RegisterContextLLDB.h:195 // Get the CFA register for a given frame. + bool ReadFrameAddress(lldb::RegisterKind register_kind, jasonmolenda wrote: > Comment update, e.g. Get the Frame Address register for a given frame. Yes, thanks for pointing to that! Comment at: source/Symbol/UnwindPlan.cpp:202 + m_afa_value.Dump(s, unwind_plan, thread); + s.Printf(" => "); jasonmolenda wrote: > What do you think about only printing the AFA= entry if it is != > LLDB_INVALID_ADDRESS? Yes, sure! Repository: rLLDB LLDB https://reviews.llvm.org/D53435 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53435: [x86] Fix issues with a realigned stack in MSVC compiled applications
aleksandr.urakov updated this revision to Diff 171650. aleksandr.urakov marked 2 inline comments as done. aleksandr.urakov added a comment. Update the patch according to comments. https://reviews.llvm.org/D53435 Files: include/lldb/Symbol/UnwindPlan.h source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Plugins/Process/Utility/RegisterContextLLDB.h source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h source/Symbol/UnwindPlan.cpp unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Index: unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp === --- unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp @@ -133,7 +133,7 @@ namespace lldb_private { static std::ostream &operator<<(std::ostream &OS, -const UnwindPlan::Row::CFAValue &CFA) { +const UnwindPlan::Row::FAValue &CFA) { StreamString S; CFA.Dump(S, nullptr, nullptr); return OS << S.GetData(); @@ -2368,7 +2368,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue esp_plus_4, esp_plus_8, ebp_plus_8; + UnwindPlan::Row::FAValue esp_plus_4, esp_plus_8, ebp_plus_8; esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); ebp_plus_8.SetIsRegisterPlusOffset(k_ebp, 8); @@ -2402,7 +2402,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; + UnwindPlan::Row::FAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; rsp_plus_8.SetIsRegisterPlusOffset(k_rsp, 8); rsp_plus_16.SetIsRegisterPlusOffset(k_rsp, 16); rbp_plus_16.SetIsRegisterPlusOffset(k_rbp, 16); @@ -2416,6 +2416,65 @@ plan.GetRowForFunctionOffset(sizeof(data) - 1)->GetCFAValue()); } +TEST_F(Testx86AssemblyInspectionEngine, TestStackRealignMSVC_i386) { + std::unique_ptr engine = Geti386Inspector(); + + uint8_t data[] = { + 0x53, // offset 00 -- pushl %ebx + 0x8b, 0xdc, // offset 01 -- movl %esp, %ebx + 0x83, 0xec, 0x08, // offset 03 -- subl $8, %esp + 0x81, 0xe4, 0x00, 0xff, 0xff, 0xff, // offset 06 -- andl $-256, %esp + 0x83, 0xc4, 0x04, // offset 12 -- addl $4, %esp + 0x55, // offset 15 -- pushl %ebp + 0x8b, 0xec, // offset 16 -- movl %esp, %ebp + 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // offset 18 -- subl $512, %esp + 0x89, 0x7d, 0xfc, // offset 24 -- movl %edi, -4(%ebp) + 0x8b, 0xe5, // offset 27 -- movl %ebp, %esp + 0x5d, // offset 29 -- popl %ebp + 0x8b, 0xe3, // offset 30 -- movl %ebx, %esp + 0x5b, // offset 32 -- popl %ebx + 0xc3// offset 33 -- retl + }; + + AddressRange sample_range(0x1000, sizeof(data)); + UnwindPlan plan(eRegisterKindLLDB); + ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), + sample_range, plan)); + + UnwindPlan::Row::FAValue esp_minus_4, esp_plus_0, esp_plus_4, esp_plus_8, + ebx_plus_8, ebp_plus_0; + esp_minus_4.SetIsRegisterPlusOffset(k_esp, -4); + esp_plus_0.SetIsRegisterPlusOffset(k_esp, 0); + esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); + esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); + ebx_plus_8.SetIsRegisterPlusOffset(k_ebx, 8); + ebp_plus_0.SetIsRegisterPlusOffset(k_ebp, 0); + + // Test CFA + EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(0)->GetCFAValue()); + EXPECT_EQ(esp_plus_8, plan.GetRowForFunctionOffset(1)->GetCFAValue()); + for (size_t i = 3; i < 33; ++i) +EXPECT_EQ(ebx_plus_8, plan.GetRowForFunctionOffset(i)->GetCFAValue()) +<< "i: " << i; + EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(33)->GetCFAValue()); + + // Test AFA + EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(12)->GetAFAValue()); + EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOffset(15)->GetAFAValue()); + EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(16)->GetAFAValue()); + for (size_t i = 18; i < 30; ++i) +EXPECT_EQ(ebp_plus_0, plan.GetRowForFunctionOffset(i)->GetAFAValue()) +<< "i: " << i; + EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOffset(30)->GetAFAValue()); + + // Test saved register + UnwindPlan
[Lldb-commits] [PATCH] D53435: [x86] Fix issues with a realigned stack in MSVC compiled applications
This revision was automatically updated to reflect the committed changes. Closed by commit rLLDB345577: [x86] Fix issues with a realigned stack in MSVC compiled applications (authored by aleksandr.urakov, committed by ). Repository: rLLDB LLDB https://reviews.llvm.org/D53435 Files: include/lldb/Symbol/UnwindPlan.h source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Plugins/Process/Utility/RegisterContextLLDB.h source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h source/Symbol/UnwindPlan.cpp unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Index: unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp === --- unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp @@ -133,7 +133,7 @@ namespace lldb_private { static std::ostream &operator<<(std::ostream &OS, -const UnwindPlan::Row::CFAValue &CFA) { +const UnwindPlan::Row::FAValue &CFA) { StreamString S; CFA.Dump(S, nullptr, nullptr); return OS << S.GetData(); @@ -2368,7 +2368,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue esp_plus_4, esp_plus_8, ebp_plus_8; + UnwindPlan::Row::FAValue esp_plus_4, esp_plus_8, ebp_plus_8; esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); ebp_plus_8.SetIsRegisterPlusOffset(k_ebp, 8); @@ -2402,7 +2402,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; + UnwindPlan::Row::FAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; rsp_plus_8.SetIsRegisterPlusOffset(k_rsp, 8); rsp_plus_16.SetIsRegisterPlusOffset(k_rsp, 16); rbp_plus_16.SetIsRegisterPlusOffset(k_rbp, 16); @@ -2416,6 +2416,65 @@ plan.GetRowForFunctionOffset(sizeof(data) - 1)->GetCFAValue()); } +TEST_F(Testx86AssemblyInspectionEngine, TestStackRealignMSVC_i386) { + std::unique_ptr engine = Geti386Inspector(); + + uint8_t data[] = { + 0x53, // offset 00 -- pushl %ebx + 0x8b, 0xdc, // offset 01 -- movl %esp, %ebx + 0x83, 0xec, 0x08, // offset 03 -- subl $8, %esp + 0x81, 0xe4, 0x00, 0xff, 0xff, 0xff, // offset 06 -- andl $-256, %esp + 0x83, 0xc4, 0x04, // offset 12 -- addl $4, %esp + 0x55, // offset 15 -- pushl %ebp + 0x8b, 0xec, // offset 16 -- movl %esp, %ebp + 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // offset 18 -- subl $512, %esp + 0x89, 0x7d, 0xfc, // offset 24 -- movl %edi, -4(%ebp) + 0x8b, 0xe5, // offset 27 -- movl %ebp, %esp + 0x5d, // offset 29 -- popl %ebp + 0x8b, 0xe3, // offset 30 -- movl %ebx, %esp + 0x5b, // offset 32 -- popl %ebx + 0xc3// offset 33 -- retl + }; + + AddressRange sample_range(0x1000, sizeof(data)); + UnwindPlan plan(eRegisterKindLLDB); + ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), + sample_range, plan)); + + UnwindPlan::Row::FAValue esp_minus_4, esp_plus_0, esp_plus_4, esp_plus_8, + ebx_plus_8, ebp_plus_0; + esp_minus_4.SetIsRegisterPlusOffset(k_esp, -4); + esp_plus_0.SetIsRegisterPlusOffset(k_esp, 0); + esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); + esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); + ebx_plus_8.SetIsRegisterPlusOffset(k_ebx, 8); + ebp_plus_0.SetIsRegisterPlusOffset(k_ebp, 0); + + // Test CFA + EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(0)->GetCFAValue()); + EXPECT_EQ(esp_plus_8, plan.GetRowForFunctionOffset(1)->GetCFAValue()); + for (size_t i = 3; i < 33; ++i) +EXPECT_EQ(ebx_plus_8, plan.GetRowForFunctionOffset(i)->GetCFAValue()) +<< "i: " << i; + EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(33)->GetCFAValue()); + + // Test AFA + EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(12)->GetAFAValue()); + EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOffset(15)->GetAFAValue()); + EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(16)->GetAFAValue()); + for (size_t i = 18; i < 30; ++i) +EXPECT_EQ(ebp_plus_0, plan.GetRowForFunctionOffset(i)->GetAFAValue()) +<< "i: " << i; + EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOff
[Lldb-commits] [PATCH] D53435: [x86] Fix issues with a realigned stack in MSVC compiled applications
This revision was automatically updated to reflect the committed changes. Closed by commit rL345577: [x86] Fix issues with a realigned stack in MSVC compiled applications (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53435?vs=171650&id=171651#toc Repository: rL LLVM https://reviews.llvm.org/D53435 Files: lldb/trunk/include/lldb/Symbol/UnwindPlan.h lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp lldb/trunk/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h lldb/trunk/source/Symbol/UnwindPlan.cpp lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Index: lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp === --- lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ lldb/trunk/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp @@ -133,7 +133,7 @@ namespace lldb_private { static std::ostream &operator<<(std::ostream &OS, -const UnwindPlan::Row::CFAValue &CFA) { +const UnwindPlan::Row::FAValue &CFA) { StreamString S; CFA.Dump(S, nullptr, nullptr); return OS << S.GetData(); @@ -2368,7 +2368,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue esp_plus_4, esp_plus_8, ebp_plus_8; + UnwindPlan::Row::FAValue esp_plus_4, esp_plus_8, ebp_plus_8; esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); ebp_plus_8.SetIsRegisterPlusOffset(k_ebp, 8); @@ -2402,7 +2402,7 @@ ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), sample_range, plan)); - UnwindPlan::Row::CFAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; + UnwindPlan::Row::FAValue rsp_plus_8, rsp_plus_16, rbp_plus_16; rsp_plus_8.SetIsRegisterPlusOffset(k_rsp, 8); rsp_plus_16.SetIsRegisterPlusOffset(k_rsp, 16); rbp_plus_16.SetIsRegisterPlusOffset(k_rbp, 16); @@ -2416,6 +2416,65 @@ plan.GetRowForFunctionOffset(sizeof(data) - 1)->GetCFAValue()); } +TEST_F(Testx86AssemblyInspectionEngine, TestStackRealignMSVC_i386) { + std::unique_ptr engine = Geti386Inspector(); + + uint8_t data[] = { + 0x53, // offset 00 -- pushl %ebx + 0x8b, 0xdc, // offset 01 -- movl %esp, %ebx + 0x83, 0xec, 0x08, // offset 03 -- subl $8, %esp + 0x81, 0xe4, 0x00, 0xff, 0xff, 0xff, // offset 06 -- andl $-256, %esp + 0x83, 0xc4, 0x04, // offset 12 -- addl $4, %esp + 0x55, // offset 15 -- pushl %ebp + 0x8b, 0xec, // offset 16 -- movl %esp, %ebp + 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // offset 18 -- subl $512, %esp + 0x89, 0x7d, 0xfc, // offset 24 -- movl %edi, -4(%ebp) + 0x8b, 0xe5, // offset 27 -- movl %ebp, %esp + 0x5d, // offset 29 -- popl %ebp + 0x8b, 0xe3, // offset 30 -- movl %ebx, %esp + 0x5b, // offset 32 -- popl %ebx + 0xc3// offset 33 -- retl + }; + + AddressRange sample_range(0x1000, sizeof(data)); + UnwindPlan plan(eRegisterKindLLDB); + ASSERT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(data, sizeof(data), + sample_range, plan)); + + UnwindPlan::Row::FAValue esp_minus_4, esp_plus_0, esp_plus_4, esp_plus_8, + ebx_plus_8, ebp_plus_0; + esp_minus_4.SetIsRegisterPlusOffset(k_esp, -4); + esp_plus_0.SetIsRegisterPlusOffset(k_esp, 0); + esp_plus_4.SetIsRegisterPlusOffset(k_esp, 4); + esp_plus_8.SetIsRegisterPlusOffset(k_esp, 8); + ebx_plus_8.SetIsRegisterPlusOffset(k_ebx, 8); + ebp_plus_0.SetIsRegisterPlusOffset(k_ebp, 0); + + // Test CFA + EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(0)->GetCFAValue()); + EXPECT_EQ(esp_plus_8, plan.GetRowForFunctionOffset(1)->GetCFAValue()); + for (size_t i = 3; i < 33; ++i) +EXPECT_EQ(ebx_plus_8, plan.GetRowForFunctionOffset(i)->GetCFAValue()) +<< "i: " << i; + EXPECT_EQ(esp_plus_4, plan.GetRowForFunctionOffset(33)->GetCFAValue()); + + // Test AFA + EXPECT_EQ(esp_plus_0, plan.GetRowForFunctionOffset(12)->GetAFAValue()); + EXPECT_EQ(esp_minus_4, plan.GetRowForFunctionOffset(15)->GetAFAValue()); + EXPECT_EQ(esp_plus
[Lldb-commits] [PATCH] D53822: [NativePDB] Add tests for dumping global variables of class type
aleksandr.urakov accepted this revision. aleksandr.urakov added a comment. This revision is now accepted and ready to land. Looks awesome, thank you! https://reviews.llvm.org/D53822 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53506: [ClangASTContext] Extract VTable pointers from C++ objects
aleksandr.urakov added a comment. Ping! Can you take a look at this, please? Repository: rLLDB LLDB https://reviews.llvm.org/D53506 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `MSVCUndecoratedNameParser`
aleksandr.urakov updated this revision to Diff 171707. aleksandr.urakov retitled this revision from "[PDB] Introduce `PDBNameParser`" to "[PDB] Introduce `MSVCUndecoratedNameParser`". aleksandr.urakov edited the summary of this revision. aleksandr.urakov added a reviewer: shafik. aleksandr.urakov added a comment. Update the diff according to the discussion, making it possible to parse MSVC demangled names by `CPlusPlusLanguage`. The old PDB plugin still uses `MSVCUndecoratedNameParser` directly because: - we are sure that the name in PDB is an MSVC name; - it has a more convenient interface, especially for restoring namespaces from the parsed name. https://reviews.llvm.org/D52461 Files: lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp lit/SymbolFile/PDB/ast-restore.test source/Plugins/Language/CPlusPlus/CMakeLists.txt source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -187,7 +187,7 @@ const llvm::pdb::PDBSymbolCompiland &pdb_compiland, llvm::DenseMap &index_map) const; - void FindTypesByName(const std::string &name, + void FindTypesByName(llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types); Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -9,6 +9,9 @@ #include "SymbolFilePDB.h" +#include "PDBASTParser.h" +#include "PDBLocationToDWARFExpression.h" + #include "clang/Lex/Lexer.h" #include "lldb/Core/Module.h" @@ -46,9 +49,8 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" -#include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" #include @@ -1063,7 +1065,7 @@ lldbassert(sc.module_sp.get()); if (!name.GetStringRef().equals( -PDBASTParser::PDBNameDropScope(pdb_data->getName( +MSVCUndecoratedNameParser::DropScope(pdb_data->getName( continue; sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); @@ -1170,22 +1172,11 @@ // Class. We won't bother to check if the parent is UDT or Enum here. m_func_method_names.Append(ConstString(name), uid); -ConstString cstr_name(name); - // To search a method name, like NS::Class:MemberFunc, LLDB searches // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does // not have inforamtion of this, we extract base names and cache them // by our own effort. -llvm::StringRef basename; -CPlusPlusLanguage::MethodName cpp_method(cstr_name); -if (cpp_method.IsValid()) { - llvm::StringRef context; - basename = cpp_method.GetBasename(); - if (basename.empty()) -CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), - context, basename); -} - +llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); if (!basename.empty()) m_func_base_names.Append(ConstString(basename), uid); else { @@ -1198,11 +1189,12 @@ } else { // Handle not-method symbols. -// The function name might contain namespace, or its lexical scope. It -// is not safe to get its base name by applying same scheme as we deal -// with the method names. -// FIXME: Remove namespace if function is static in a scope. -m_func_base_names.Append(ConstString(name), uid); +// The function name might contain namespace, or its lexical scope. +llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); +if (!basename.empty()) + m_func_base_names.Append(ConstString(basename), uid); +else + m_func_base_names.Append(ConstString(name), uid); if (name == "main") { m_func_full_names.Append(ConstString(name), uid); @@ -1348,10 +1340,8 @@ searched_symbol_files.clear(); searched_symbol_files.insert(this); - std
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `MSVCUndecoratedNameParser`
aleksandr.urakov added a comment. In https://reviews.llvm.org/D52461#1281742, @zturner wrote: > What do you think? Yes, it's a really cool idea! When I was starting the implementation of the parser from this patch, I thought that it would be good to have mangled names instead - then we could retrieve fully structured names (with all its scope specifiers, template parameters etc.), but I didn't know that we actually have them on the lower level! I want to join the development of the new PDB plugin, but some time later - may be in a month or two. I want to contribute now all changes I made to support expressions on Windows, and then I have some LLVM unrelated work to do. But I think that the way you suggest to solve the problem from the patch is the really right way to do it, and I'm planning to implement it when I'll join the new plugin development. But is the MSVC demangled names parsing really necessary for `CPlusPlusLanguage`? Can such names ever somehow occur there? May be (if they can't) we could move this parser back to the old PDB plugin, and then drop it as a weirder solution when the new plugin will be done? Then we could commit this as a solution for the old PDB plugin to proceed with some dependent (and not related to the old PDB plugin) patches? https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53951: [NativePDB] Get LLDB types from PDB function types
aleksandr.urakov accepted this revision. aleksandr.urakov added a comment. This revision is now accepted and ready to land. Looks good, thanks! https://reviews.llvm.org/D53951 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52618: [Windows] A basic implementation of memory allocations in a debuggee process
This revision was automatically updated to reflect the committed changes. Closed by commit rL345815: [Windows] A basic implementation of memory allocations in a debuggee process (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D52618?vs=167338&id=172097#toc Repository: rL LLVM https://reviews.llvm.org/D52618 Files: lldb/trunk/lit/Expr/TestIRMemoryMap.test lldb/trunk/lit/Expr/TestIRMemoryMapWindows.test lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h Index: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h === --- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h +++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -84,6 +84,9 @@ Status &error) override; size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override; + lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, +Status &error) override; + Status DoDeallocateMemory(lldb::addr_t ptr) override; Status GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override; Index: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp === --- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -72,6 +72,20 @@ return file_name; } +DWORD ConvertLldbToWinApiProtect(uint32_t protect) { + // We also can process a read / write permissions here, but if the debugger + // will make later a write into the allocated memory, it will fail. To get + // around it is possible inside DoWriteMemory to remember memory permissions, + // allow write, write and restore permissions, but for now we process only + // the executable permission. + // + // TODO: Process permissions other than executable + if (protect & ePermissionsExecutable) +return PAGE_EXECUTE_READWRITE; + + return PAGE_READWRITE; +} + } // anonymous namespace namespace lldb_private { @@ -695,6 +709,58 @@ return bytes_written; } +lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) { + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size, + permissions); + + if (!m_session_data) { +LLDB_LOG(log, "cannot allocate, there is no active debugger connection."); +error.SetErrorString( +"cannot allocate, there is no active debugger connection"); +return 0; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + auto protect = ConvertLldbToWinApiProtect(permissions); + auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect); + if (!result) { +error.SetError(GetLastError(), eErrorTypeWin32); +LLDB_LOG(log, "allocating failed with error: {0}", error); +return 0; + } + + return reinterpret_cast(result); +} + +Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) { + Status result; + + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr); + + if (!m_session_data) { +LLDB_LOG(log, "cannot deallocate, there is no active debugger connection."); +result.SetErrorString( +"cannot deallocate, there is no active debugger connection"); +return result; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + if (!VirtualFreeEx(handle, reinterpret_cast(ptr), 0, MEM_RELEASE)) { +result.SetError(GetLastError(), eErrorTypeWin32); +LLDB_LOG(log, "deallocating failed with error: {0}", result); +return result; + } + + return result; +} + Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); Index: lldb/trunk/lit/Expr/TestIRMemoryMapWindows.test === --- lldb/trunk/lit/Expr/TestIRMemoryMapWindows.test +++ lldb/trunk/lit/Expr/TestIRMemoryMapWindows.test @@ -0,0 +1,12 @@ +# REQUIRES: windows + +# RUN: clang-cl /Zi %p/Inputs/call-function.cpp -o %t + +# RUN: lldb-test ir-memory-map %t %S/Inputs/ir-memory-map-basic +# RUN: lldb-test ir-memory-map -hos
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `MSVCUndecoratedNameParser`
aleksandr.urakov marked 2 inline comments as done. aleksandr.urakov added a comment. Thank you for comments! I've updated the patch. https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `MSVCUndecoratedNameParser`
aleksandr.urakov updated this revision to Diff 172101. https://reviews.llvm.org/D52461 Files: lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp lit/SymbolFile/PDB/ast-restore.test source/Plugins/Language/CPlusPlus/CMakeLists.txt source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp Index: unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp === --- unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -138,7 +138,14 @@ {"std::vector>" "::_M_emplace_back_aux", "std::vector>", - "_M_emplace_back_aux"}}; + "_M_emplace_back_aux"}, + {"`anonymous namespace'::foo", "`anonymous namespace'", "foo"}, + {"`operator<'::`2'::B<0>::operator>", + "`operator<'::`2'::B<0>", + "operator>"}, + {"`anonymous namespace'::S::<<::__l2::Foo", + "`anonymous namespace'::S::<<::__l2", + "Foo"}}; llvm::StringRef context, basename; for (const auto &test : test_cases) { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -187,7 +187,7 @@ const llvm::pdb::PDBSymbolCompiland &pdb_compiland, llvm::DenseMap &index_map) const; - void FindTypesByName(const std::string &name, + void FindTypesByName(llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types); Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -9,6 +9,9 @@ #include "SymbolFilePDB.h" +#include "PDBASTParser.h" +#include "PDBLocationToDWARFExpression.h" + #include "clang/Lex/Lexer.h" #include "lldb/Core/Module.h" @@ -46,9 +49,8 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" -#include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" #include @@ -1063,7 +1065,7 @@ lldbassert(sc.module_sp.get()); if (!name.GetStringRef().equals( -PDBASTParser::PDBNameDropScope(pdb_data->getName( +MSVCUndecoratedNameParser::DropScope(pdb_data->getName( continue; sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); @@ -1170,22 +1172,11 @@ // Class. We won't bother to check if the parent is UDT or Enum here. m_func_method_names.Append(ConstString(name), uid); -ConstString cstr_name(name); - // To search a method name, like NS::Class:MemberFunc, LLDB searches // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does // not have inforamtion of this, we extract base names and cache them // by our own effort. -llvm::StringRef basename; -CPlusPlusLanguage::MethodName cpp_method(cstr_name); -if (cpp_method.IsValid()) { - llvm::StringRef context; - basename = cpp_method.GetBasename(); - if (basename.empty()) -CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), - context, basename); -} - +llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); if (!basename.empty()) m_func_base_names.Append(ConstString(basename), uid); else { @@ -1198,11 +1189,12 @@ } else { // Handle not-method symbols. -// The function name might contain namespace, or its lexical scope. It -// is not safe to get its base name by applying same scheme as we deal -// with the method names. -// FIXME: Remove namespace if function is static in a scope. -m_func_base_names.Append(ConstString(name), uid); +// The function name might contain namespace, or its lexical scope. +llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); +if (!basename.empty()) + m_func_base_names.Append(ConstString(basename), uid); +else + m_func_base_names.A
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `MSVCUndecoratedNameParser`
aleksandr.urakov updated this revision to Diff 172102. https://reviews.llvm.org/D52461 Files: lit/SymbolFile/PDB/Inputs/AstRestoreTest.cpp lit/SymbolFile/PDB/ast-restore.test source/Plugins/Language/CPlusPlus/CMakeLists.txt source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h source/Plugins/SymbolFile/PDB/PDBASTParser.cpp source/Plugins/SymbolFile/PDB/PDBASTParser.h source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp Index: unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp === --- unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -138,7 +138,14 @@ {"std::vector>" "::_M_emplace_back_aux", "std::vector>", - "_M_emplace_back_aux"}}; + "_M_emplace_back_aux"}, + {"`anonymous namespace'::foo", "`anonymous namespace'", "foo"}, + {"`operator<'::`2'::B<0>::operator>", + "`operator<'::`2'::B<0>", + "operator>"}, + {"`anonymous namespace'::S::<<::__l2::Foo", + "`anonymous namespace'::S::<<::__l2", + "Foo"}}; llvm::StringRef context, basename; for (const auto &test : test_cases) { Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -187,7 +187,7 @@ const llvm::pdb::PDBSymbolCompiland &pdb_compiland, llvm::DenseMap &index_map) const; - void FindTypesByName(const std::string &name, + void FindTypesByName(llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types); Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp === --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -9,6 +9,9 @@ #include "SymbolFilePDB.h" +#include "PDBASTParser.h" +#include "PDBLocationToDWARFExpression.h" + #include "clang/Lex/Lexer.h" #include "lldb/Core/Module.h" @@ -46,9 +49,8 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" -#include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" #include @@ -1063,7 +1065,7 @@ lldbassert(sc.module_sp.get()); if (!name.GetStringRef().equals( -PDBASTParser::PDBNameDropScope(pdb_data->getName( +MSVCUndecoratedNameParser::DropScope(pdb_data->getName( continue; sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); @@ -1170,22 +1172,11 @@ // Class. We won't bother to check if the parent is UDT or Enum here. m_func_method_names.Append(ConstString(name), uid); -ConstString cstr_name(name); - // To search a method name, like NS::Class:MemberFunc, LLDB searches // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does // not have inforamtion of this, we extract base names and cache them // by our own effort. -llvm::StringRef basename; -CPlusPlusLanguage::MethodName cpp_method(cstr_name); -if (cpp_method.IsValid()) { - llvm::StringRef context; - basename = cpp_method.GetBasename(); - if (basename.empty()) -CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), - context, basename); -} - +llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); if (!basename.empty()) m_func_base_names.Append(ConstString(basename), uid); else { @@ -1198,11 +1189,12 @@ } else { // Handle not-method symbols. -// The function name might contain namespace, or its lexical scope. It -// is not safe to get its base name by applying same scheme as we deal -// with the method names. -// FIXME: Remove namespace if function is static in a scope. -m_func_base_names.Append(ConstString(name), uid); +// The function name might contain namespace, or its lexical scope. +llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); +if (!basename.empty()) + m_func_base_names.Append(ConstString(basename), uid); +else + m_func_base_names.A
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. Ping! Can you look at this, please? https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53915: [FileSystem] Move resolve logic out of FileSpec
aleksandr.urakov added a comment. This commit breaks the Windows build. Repository: rL LLVM https://reviews.llvm.org/D53915 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53915: [FileSystem] Move resolve logic out of FileSpec
aleksandr.urakov added a comment. It's ok, I was able to fix it myself. Here is the commit: r345956 Repository: rL LLVM https://reviews.llvm.org/D53915 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. Thank you! https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
This revision was automatically updated to reflect the committed changes. Closed by commit rLLDB345957: [Symbol] Search symbols with name and type in a symbol file (authored by aleksandr.urakov, committed by ). Repository: rLLDB LLDB https://reviews.llvm.org/D53368 Files: include/lldb/Symbol/SymbolFile.h include/lldb/Symbol/SymbolVendor.h source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp source/Plugins/SymbolFile/PDB/SymbolFilePDB.h source/Symbol/SymbolVendor.cpp unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp Index: include/lldb/Symbol/SymbolVendor.h === --- include/lldb/Symbol/SymbolVendor.h +++ include/lldb/Symbol/SymbolVendor.h @@ -165,6 +165,8 @@ // file) std::unique_ptr m_sym_file_ap; // A single symbol file. Subclasses // can add more of these if needed. + Symtab *m_symtab; // Save a symtab once to not pass it through `AddSymbols` of +// the symbol file each time when it is needed private: //-- Index: include/lldb/Symbol/SymbolFile.h === --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -214,6 +214,8 @@ return {}; } + virtual void AddSymbols(Symtab &symtab) {} + //-- /// Notify the SymbolFile that the file addresses in the Sections /// for this module have been changed. Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp === --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -621,3 +621,20 @@ EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared(fspec, aspec); + + SymbolContextList sc_list; + EXPECT_EQ(1u, +module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), + lldb::eSymbolTypeAny, sc_list)); + EXPECT_EQ(1u, sc_list.GetSize()); + + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_STREQ("int foo(int)", + sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); +} Index: source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp === --- source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -124,7 +124,6 @@ if (delegate_sp) delegate_sp->PopulateSymtab(this, *m_symtab_ap); // TODO: get symbols from delegate - m_symtab_ap->Finalize(); } } return m_symtab_ap.get(); Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp === --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2876,8 +2876,6 @@ // do the section lookup next time. if (m_symtab_ap == nullptr) m_symtab_ap.reset(new Symtab(this)); - -m_symtab_ap->CalculateSymbolSizes(); } return m_symtab_ap.get(); Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp === --- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1315,7 +1315,6 @@ std::lock_guard symtab_guard( m_symtab_ap->GetMutex()); ParseSymtab(); - m_symtab_ap->Finalize(); } } return m_symtab_ap.get(); @@ -4807,16 +4806,6 @@ } } -//StreamFile s(stdout, false); -//s.Printf ("Symbol table before CalculateSymbolSizes():\n"); -//symtab->Dump(&s, NULL, eSortOrderNone); -// Set symbol byte sizes correctly since mach-o nlist entries don't have -// sizes -symtab->CalculateSymbolSizes(); - -//s.Printf ("Symbol table after CalculateSymbolSizes():\n"); -//symtab->Dump(&s, NULL, eSortOrderNone); - return symtab->GetNumSymbols(); } return 0; Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp === --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -651,7 +651,6 @@ symbols[i].SetDebug(true); } } - m_symtab_ap->Cal
[Lldb-commits] [PATCH] D54031: [NativePDB] Make tests work on x86 too
aleksandr.urakov created this revision. aleksandr.urakov added reviewers: zturner, stella.stamenova. aleksandr.urakov added a project: LLDB. Herald added subscribers: lldb-commits, teemperor. This patch fixes the NativePDB tests to make them work from x86 command line too. Repository: rLLDB LLDB https://reviews.llvm.org/D54031 Files: lit/SymbolFile/NativePDB/disassembly.cpp lit/SymbolFile/NativePDB/simple-breakpoints.cpp lit/SymbolFile/NativePDB/tag-types.cpp Index: lit/SymbolFile/NativePDB/tag-types.cpp === --- lit/SymbolFile/NativePDB/tag-types.cpp +++ lit/SymbolFile/NativePDB/tag-types.cpp @@ -141,7 +141,7 @@ } // CHECK: (lldb) target create "{{.*}}tag-types.cpp.tmp.exe" -// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' (x86_64). +// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' // CHECK-NEXT: (lldb) command source -s 0 '{{.*}}tag-types.lldbinit' // CHECK-NEXT: Executing commands in '{{.*}}tag-types.lldbinit'. // CHECK-NEXT: (lldb) type lookup -- Struct Index: lit/SymbolFile/NativePDB/simple-breakpoints.cpp === --- lit/SymbolFile/NativePDB/simple-breakpoints.cpp +++ lit/SymbolFile/NativePDB/simple-breakpoints.cpp @@ -35,30 +35,30 @@ // CHECK: (lldb) target create "{{.*}}simple-breakpoints.cpp.tmp.exe" -// CHECK: Current executable set to '{{.*}}simple-breakpoints.cpp.tmp.exe' (x86_64). +// CHECK: Current executable set to '{{.*}}simple-breakpoints.cpp.tmp.exe' // CHECK: (lldb) break set -n main -// CHECK: Breakpoint 1: where = simple-breakpoints.cpp.tmp.exe`main + 21 +// CHECK: Breakpoint 1: where = simple-breakpoints.cpp.tmp.exe`main + {{[0-9]+}} // CHECK-SAME: at simple-breakpoints.cpp:31 // CHECK: (lldb) break set -n OvlGlobalFn // CHECK: Breakpoint 2: 3 locations. // CHECK: (lldb) break set -n StaticFn -// CHECK: Breakpoint 3: where = simple-breakpoints.cpp.tmp.exe`StaticFn + 5 +// CHECK: Breakpoint 3: where = simple-breakpoints.cpp.tmp.exe`StaticFn + {{[0-9]+}} // CHECK-SAME: at simple-breakpoints.cpp:24 // CHECK: (lldb) break set -n DoesntExist // CHECK: Breakpoint 4: no locations (pending). // CHECK: (lldb) break list // CHECK: Current breakpoints: // CHECK: 1: name = 'main', locations = 1 -// CHECK:1.1: where = simple-breakpoints.cpp.tmp.exe`main + 21 +// CHECK:1.1: where = simple-breakpoints.cpp.tmp.exe`main + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:31 // CHECK: 2: name = 'OvlGlobalFn', locations = 3 -// CHECK:2.1: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + 5 +// CHECK:2.1: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:13 // CHECK:2.2: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn // CHECK-SAME:at simple-breakpoints.cpp:16 -// CHECK:2.3: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + 17 +// CHECK:2.3: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:20 // CHECK: 3: name = 'StaticFn', locations = 1 -// CHECK:3.1: where = simple-breakpoints.cpp.tmp.exe`StaticFn + 5 +// CHECK:3.1: where = simple-breakpoints.cpp.tmp.exe`StaticFn + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:24 // CHECK: 4: name = 'DoesntExist', locations = 0 (pending) Index: lit/SymbolFile/NativePDB/disassembly.cpp === --- lit/SymbolFile/NativePDB/disassembly.cpp +++ lit/SymbolFile/NativePDB/disassembly.cpp @@ -2,7 +2,7 @@ // REQUIRES: lld // Test that we can show disassembly and source. -// RUN: clang-cl /Z7 /GS- /GR- /c /Fo%t.obj -- %s +// RUN: clang-cl -m64 /Z7 /GS- /GR- /c /Fo%t.obj -- %s // RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb -- %t.obj // RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb -f %t.exe -s \ // RUN: %p/Inputs/disassembly.lldbinit | FileCheck %s Index: lit/SymbolFile/NativePDB/tag-types.cpp === --- lit/SymbolFile/NativePDB/tag-types.cpp +++ lit/SymbolFile/NativePDB/tag-types.cpp @@ -141,7 +141,7 @@ } // CHECK: (lldb) target create "{{.*}}tag-types.cpp.tmp.exe" -// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' (x86_64). +// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' // CHECK-NEXT: (lldb) command source -s 0 '{{.*}}tag-types.lldbinit' // CHECK-NEXT: Executing commands in '{{.*}}tag-types.lldbinit'. // CHECK-NEXT: (lldb) type lookup -- Struct Index: lit/SymbolFile/NativePDB/simple-breakpoints.cpp
[Lldb-commits] [PATCH] D54031: [NativePDB] Make tests work on x86 too
aleksandr.urakov added a comment. Thanks! Repository: rLLDB LLDB https://reviews.llvm.org/D54031 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D54031: [NativePDB] Make tests work on x86 too
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL345974: [NativePDB] Make tests work on x86 too (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D54031?vs=172328&id=172352#toc Repository: rL LLVM https://reviews.llvm.org/D54031 Files: lldb/trunk/lit/SymbolFile/NativePDB/disassembly.cpp lldb/trunk/lit/SymbolFile/NativePDB/simple-breakpoints.cpp lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp Index: lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp === --- lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp +++ lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp @@ -141,7 +141,7 @@ } // CHECK: (lldb) target create "{{.*}}tag-types.cpp.tmp.exe" -// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' (x86_64). +// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' // CHECK-NEXT: (lldb) command source -s 0 '{{.*}}tag-types.lldbinit' // CHECK-NEXT: Executing commands in '{{.*}}tag-types.lldbinit'. // CHECK-NEXT: (lldb) type lookup -- Struct Index: lldb/trunk/lit/SymbolFile/NativePDB/simple-breakpoints.cpp === --- lldb/trunk/lit/SymbolFile/NativePDB/simple-breakpoints.cpp +++ lldb/trunk/lit/SymbolFile/NativePDB/simple-breakpoints.cpp @@ -35,30 +35,30 @@ // CHECK: (lldb) target create "{{.*}}simple-breakpoints.cpp.tmp.exe" -// CHECK: Current executable set to '{{.*}}simple-breakpoints.cpp.tmp.exe' (x86_64). +// CHECK: Current executable set to '{{.*}}simple-breakpoints.cpp.tmp.exe' // CHECK: (lldb) break set -n main -// CHECK: Breakpoint 1: where = simple-breakpoints.cpp.tmp.exe`main + 21 +// CHECK: Breakpoint 1: where = simple-breakpoints.cpp.tmp.exe`main + {{[0-9]+}} // CHECK-SAME: at simple-breakpoints.cpp:31 // CHECK: (lldb) break set -n OvlGlobalFn // CHECK: Breakpoint 2: 3 locations. // CHECK: (lldb) break set -n StaticFn -// CHECK: Breakpoint 3: where = simple-breakpoints.cpp.tmp.exe`StaticFn + 5 +// CHECK: Breakpoint 3: where = simple-breakpoints.cpp.tmp.exe`StaticFn + {{[0-9]+}} // CHECK-SAME: at simple-breakpoints.cpp:24 // CHECK: (lldb) break set -n DoesntExist // CHECK: Breakpoint 4: no locations (pending). // CHECK: (lldb) break list // CHECK: Current breakpoints: // CHECK: 1: name = 'main', locations = 1 -// CHECK:1.1: where = simple-breakpoints.cpp.tmp.exe`main + 21 +// CHECK:1.1: where = simple-breakpoints.cpp.tmp.exe`main + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:31 // CHECK: 2: name = 'OvlGlobalFn', locations = 3 -// CHECK:2.1: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + 5 +// CHECK:2.1: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:13 // CHECK:2.2: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn // CHECK-SAME:at simple-breakpoints.cpp:16 -// CHECK:2.3: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + 17 +// CHECK:2.3: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:20 // CHECK: 3: name = 'StaticFn', locations = 1 -// CHECK:3.1: where = simple-breakpoints.cpp.tmp.exe`StaticFn + 5 +// CHECK:3.1: where = simple-breakpoints.cpp.tmp.exe`StaticFn + {{[0-9]+}} // CHECK-SAME:at simple-breakpoints.cpp:24 // CHECK: 4: name = 'DoesntExist', locations = 0 (pending) Index: lldb/trunk/lit/SymbolFile/NativePDB/disassembly.cpp === --- lldb/trunk/lit/SymbolFile/NativePDB/disassembly.cpp +++ lldb/trunk/lit/SymbolFile/NativePDB/disassembly.cpp @@ -2,7 +2,7 @@ // REQUIRES: lld // Test that we can show disassembly and source. -// RUN: clang-cl /Z7 /GS- /GR- /c /Fo%t.obj -- %s +// RUN: clang-cl -m64 /Z7 /GS- /GR- /c /Fo%t.obj -- %s // RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb -- %t.obj // RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb -f %t.exe -s \ // RUN: %p/Inputs/disassembly.lldbinit | FileCheck %s Index: lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp === --- lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp +++ lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp @@ -141,7 +141,7 @@ } // CHECK: (lldb) target create "{{.*}}tag-types.cpp.tmp.exe" -// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' (x86_64). +// CHECK-NEXT: Current executable set to '{{.*}}tag-types.cpp.tmp.exe' // CHE
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. Thanks for catching that! Unfortunately, I have no access to MacOS, can you provide some more info about failure, please? Repository: rLLDB LLDB https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. I'm not sure, but have an assumption. Here is the first green build of the green-dragon-24: http://green.lab.llvm.org/green/job/lldb-cmake/12090/ It became green after three changes, one of them is your revert of my commit, while another is Zachary's "Fix the lit test suite". I think that it's Zachary's commit fixed the build, not the revert. Moreover, my commit is Windows specific, I can't figure out, how it can break the MacOS build... So may be we will recommit it back? If it will still fail, then we could take failure logs and revert it back again. Repository: rLLDB LLDB https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D52461: [PDB] Introduce `MSVCUndecoratedNameParser`
aleksandr.urakov added a comment. Thank you! https://reviews.llvm.org/D52461 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov reopened this revision. aleksandr.urakov added a comment. This revision is now accepted and ready to land. @davide You are right, this patch was the cause of the failure, sorry for that. It seems that I've found a generic issue with this patch. Thanks again for pointing to that! @clayborg The problem is that there is a bunch of places where a symtab is retrieved directly from an object file, not from a symbol vendor. So it remains uncalculated. If we will just return the recalculation / finalization to object files, it will fix the issue, but symbols from PDB will not be available in this places. We can try to use the symbol vendor instead everywhere in this places (we can retrieve a module from an object file, and we can retrieve a symbol vendor from a module, so it is guaranteed that we can get the symbol vendor in all these places). What do you think about the such approach? What pitfalls can be with it? Repository: rLLDB LLDB https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53506: [ClangASTContext] Extract VTable pointers from C++ objects
aleksandr.urakov added a comment. Ping! Is it ok to proceed with it? Does anyone have objections? Repository: rLLDB LLDB https://reviews.llvm.org/D53506 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53368: [Symbol] Search symbols with name and type in a symbol file
aleksandr.urakov added a comment. Yes, sure. It happens in the following functions: - `Module::ResolveSymbolContextForAddress` - `DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint` through `findSymbolAddress` - `DynamicLoaderHexagonDYLD::RendezvousBreakpointHit` through `findSymbolAddress` - `JITLoaderGDB::ReadJITDescriptorImpl` - `ObjectFileELF::GetAddressClass` - `ObjectFileELF::GetSymtab` - `ObjectFileELF::RelocateSection` - `ObjectFileELF::Dump` - `ObjectFileMachO::GetAddressClass` - `ObjectFileMachO::ProcessSegmentCommand` - `SymbolFileDWARF::GetObjCClassSymbol` - `SymbolFileDWARF::ParseVariableDIE` - `SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap` - `SymbolFileDWARFDebugMap::InitOSO` - `SymbolFileDWARFDebugMap::ResolveSymbolContext` - `SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE` - `SymbolFileSymtab::CalculateAbilities` - `SymbolFileSymtab::ParseCompileUnitAtIndex` - `SymbolFileSymtab::ParseCompileUnitFunctions` - `SymbolFileSymtab::ResolveSymbolContext` - `ObjectFile::GetAddressClass` - `SymbolVendor::GetSymtab()` Repository: rLLDB LLDB https://reviews.llvm.org/D53368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D54053: [NativePDB] Add the ability to create clang record decls from mangled names.
aleksandr.urakov accepted this revision. aleksandr.urakov added a comment. In https://reviews.llvm.org/D54053#1286653, @zturner wrote: > Bleh, I think I found a problem with this approach. Since we assume > everything is a namespace, it can lead to ambiguities. I think we need to > actually consult the debug info while parsing components of the mangled name. Yes, it is what actually we have done in `PDBASTParser::GetDeclContextContainingSymbol`. Also I think that it is worth to remember if we already have created the class / function parent before, and do not create namespaces in this case. For example: `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct`. We have here the `PrivateFunc` function and the `InnerFuncStruct` structure inside it. So we do not need to create the `__l2` namespace inside the `PrivateFunc` function (moreover, it is not possible to create a namespace inside a class / function). There is a similar problem with global and static variables and functions. Are the mangled names presented for them? Can we solve it in the same way? Anyway, I think that this patch is a great start! https://reviews.llvm.org/D54053 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D54216: [NativePDB] Improve support for reconstructing a clang AST from PDB debug info
aleksandr.urakov accepted this revision. aleksandr.urakov added a comment. This revision is now accepted and ready to land. Looks good, thank you! The only question is performance, haven't you checked how much time takes the preprocessing on huge PDBs? Intuitively it seems that it shouldn't take too much time (n*log(n) where n is the count of LF_NESTTYPE records), but may be you have checked this? https://reviews.llvm.org/D54216 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D54216: [NativePDB] Improve support for reconstructing a clang AST from PDB debug info
aleksandr.urakov added a comment. In https://reviews.llvm.org/D54216#1291852, @zturner wrote: > I checked on clang.pdb. For my local build of LLVM this about 780MB. It's > quite slow in debug build (14 seconds for `ParseSectionContribs` and 60 > seconds for `PreprocessTpiStream`), but in release build the combined total > is less than 2 seconds for both function calls I think that less than 2 seconds for a 780MB PDB in release is very good! Thank you! https://reviews.llvm.org/D54216 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D54357: [NativePDB] Improved support for nested type reconstruction
aleksandr.urakov added a comment. This change looks reasonable to me for solving the problem with the current `LF_NESTTYPE` approach. But I'm not sure... Now we all the same need to analyze mangled names and make a decision based on this. Does the current `LF_NESTTYPE` approach still has advantages over the "parse-scope" approach? I'm afraid that we will have to fully analyze a mangled name in the future for scoped types, so if the `LF_NESTTYPE` approach doesn't have a significant advantages over the "parse-scope" approach, do we really need to support them both? Comment at: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp:560-576 + // If it's an inner definition, then treat whatever name we have here as a + // single component of a mangled name. So we can inject it into the parent's + // mangled name to see if it matches. + CVTagRecord child = CVTagRecord::create(tpi.getType(Record.Type)); + std::string qname = parent.asTag().getUniqueName(); + if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4) +return llvm::None; May be it would be a good idea to make the demangler (or to implement a mangler) more flexible to hide these details there? I do not mean to do it exactly in this commit, but what do you think about this at all? Comment at: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp:881-887 +// If there is no parent in the debug info, but some of the scopes have +// template params, then this is a case of bad debug info. See, for +// example, llvm.org/pr39607. We don't want to create an ambiguity between +// a NamespaceDecl and a CXXRecordDecl, so instead we create a class at +// global scope with the fully qualified name. +if (AnyScopesHaveTemplateParams(scopes)) + return {context, record.Name}; Is this a clang only bug, or MSVC also does so? I do not have anything against this solution for now, I just mean, may be we'll replace it with an `assert` when the bug will be fixed? https://reviews.llvm.org/D54357 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D53506: [ClangASTContext] Extract VTable pointers from C++ objects
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL346669: [ClangASTContext] Extract VTable pointers from C++ objects (authored by aleksandr.urakov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53506?vs=170430&id=173684#toc Repository: rL LLVM https://reviews.llvm.org/D53506 Files: lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/lit/SymbolFile/PDB/Inputs/VBases.cpp lldb/trunk/lit/SymbolFile/PDB/Inputs/VBases.script lldb/trunk/lit/SymbolFile/PDB/vbases.test lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Index: lldb/trunk/source/Core/ValueObject.cpp === --- lldb/trunk/source/Core/ValueObject.cpp +++ lldb/trunk/source/Core/ValueObject.cpp @@ -2804,31 +2804,6 @@ return result_sp; } -lldb::addr_t ValueObject::GetCPPVTableAddress(AddressType &address_type) { - CompilerType pointee_type; - CompilerType this_type(GetCompilerType()); - uint32_t type_info = this_type.GetTypeInfo(&pointee_type); - if (type_info) { -bool ptr_or_ref = false; -if (type_info & (eTypeIsPointer | eTypeIsReference)) { - ptr_or_ref = true; - type_info = pointee_type.GetTypeInfo(); -} - -const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus; -if ((type_info & cpp_class) == cpp_class) { - if (ptr_or_ref) { -address_type = GetAddressTypeOfChildren(); -return GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - } else -return GetAddressOf(false, &address_type); -} - } - - address_type = eAddressTypeInvalid; - return LLDB_INVALID_ADDRESS; -} - ValueObjectSP ValueObject::Dereference(Status &error) { if (m_deref_valobj) return m_deref_valobj->GetSP(); Index: lldb/trunk/source/Symbol/ClangASTContext.cpp === --- lldb/trunk/source/Symbol/ClangASTContext.cpp +++ lldb/trunk/source/Symbol/ClangASTContext.cpp @@ -201,6 +201,122 @@ } } +static lldb::addr_t GetVTableAddress(Process &process, + VTableContextBase &vtable_ctx, + ValueObject &valobj, + const ASTRecordLayout &record_layout) { + // Retrieve type info + CompilerType pointee_type; + CompilerType this_type(valobj.GetCompilerType()); + uint32_t type_info = this_type.GetTypeInfo(&pointee_type); + if (!type_info) +return LLDB_INVALID_ADDRESS; + + // Check if it's a pointer or reference + bool ptr_or_ref = false; + if (type_info & (eTypeIsPointer | eTypeIsReference)) { +ptr_or_ref = true; +type_info = pointee_type.GetTypeInfo(); + } + + // We process only C++ classes + const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus; + if ((type_info & cpp_class) != cpp_class) +return LLDB_INVALID_ADDRESS; + + // Calculate offset to VTable pointer + lldb::offset_t vbtable_ptr_offset = + vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity() + : 0; + + if (ptr_or_ref) { +// We have a pointer / ref to object, so read +// VTable pointer from process memory + +if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad) + return LLDB_INVALID_ADDRESS; + +auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); +if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS) + return LLDB_INVALID_ADDRESS; + +vbtable_ptr_addr += vbtable_ptr_offset; + +Status err; +return process.ReadPointerFromMemory(vbtable_ptr_addr, err); + } + + // We have an object already read from process memory, + // so just extract VTable pointer from it + + DataExtractor data; + Status err; + auto size = valobj.GetData(data, err); + if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size) +return LLDB_INVALID_ADDRESS; + + return data.GetPointer(&vbtable_ptr_offset); +} + +static int64_t ReadVBaseOffsetFromVTable(Process &process, + VTableContextBase &vtable_ctx, + lldb::addr_t vtable_ptr, + const CXXRecordDecl *cxx_record_decl, + const CXXRecordDecl *base_class_decl) { + if (vtable_ctx.isMicrosoft()) { +clang::MicrosoftVTableContext &msoft_vtable_ctx = +static_cast(vtable_ctx); + +// Get the index into the virtual base table. The +// index is the index in uint32_t from vbtable_ptr +const unsigned vbtable_index = +msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl); +const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4; +Status err; +return process.ReadSignedIntegerFromMemory(base_offset_addr, 4,