Skip to content

Conversation

Nerixyz
Copy link
Contributor

@Nerixyz Nerixyz commented Oct 2, 2025

Relands #149701 which was reverted in 185ae5c because it broke demangling of Itanium symbols on i386.

The last commit in this PR adds the fix for this (discussed in #160930). On x86 environments, the prefix of __cdecl functions will now be removed to match DWARF. I opened #161676 to discuss this for the other calling conventions.

@Nerixyz Nerixyz requested a review from JDevlieghere as a code owner October 2, 2025 14:45
@Nerixyz Nerixyz added the lldb label Oct 2, 2025
@Nerixyz Nerixyz requested review from mstorsjo and Michael137 October 2, 2025 14:45
@llvmbot
Copy link
Member

llvmbot commented Oct 2, 2025

@llvm/pr-subscribers-lldb

Author: nerix (Nerixyz)

Changes

Relands #149701 which was reverted in 185ae5c because it broke demangling of Itanium symbols on i386.

The last commit in this PR adds the fix for this (discussed in #160930). On x86 environments, the prefix of __cdecl functions will now be removed to match DWARF. I opened #161676 to discuss this for the other calling conventions.


Patch is 26.48 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/161678.diff

16 Files Affected:

  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (+12-7)
  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp (+18)
  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h (+12)
  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (+43-1)
  • (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (+8)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/break-by-function.cpp (+3-3)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/break-by-line.cpp (+1-1)
  • (added) lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp (+51)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/disassembly.cpp (+1-1)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp (+4-3)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp (+5-5)
  • (modified) lldb/test/Shell/SymbolFile/NativePDB/stack_unwinding01.cpp (+6-6)
  • (modified) lldb/test/Shell/SymbolFile/PDB/function-nested-block.test (+1-1)
  • (modified) lldb/test/Shell/SymbolFile/PDB/variables.test (+3-3)
  • (modified) lldb/unittests/SymbolFile/NativePDB/CMakeLists.txt (+1)
  • (added) lldb/unittests/SymbolFile/NativePDB/PdbUtilTests.cpp (+47)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 51bdcc92b05a8..e7fddf08967fb 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -38,16 +38,18 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
                    TypeIndex func_type_index,
                    clang::FunctionDecl *&function_decl,
                    lldb::opaque_compiler_type_t parent_ty,
-                   llvm::StringRef proc_name, CompilerType func_ct)
+                   llvm::StringRef proc_name, ConstString mangled_name,
+                   CompilerType func_ct)
       : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),
         function_decl(function_decl), parent_ty(parent_ty),
-        proc_name(proc_name), func_ct(func_ct) {}
+        proc_name(proc_name), mangled_name(mangled_name), func_ct(func_ct) {}
   PdbIndex &m_index;
   TypeSystemClang &m_clang;
   TypeIndex func_type_index;
   clang::FunctionDecl *&function_decl;
   lldb::opaque_compiler_type_t parent_ty;
   llvm::StringRef proc_name;
+  ConstString mangled_name;
   CompilerType func_ct;
 
   llvm::Error visitKnownMember(CVMemberRecord &cvr,
@@ -87,8 +89,7 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
     bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
                          MethodOptions::CompilerGenerated;
     function_decl = m_clang.AddMethodToCXXRecordType(
-        parent_ty, proc_name,
-        /*asm_label=*/{}, func_ct, /*access=*/access_type,
+        parent_ty, proc_name, mangled_name, func_ct, /*access=*/access_type,
         /*is_virtual=*/is_virtual, /*is_static=*/is_static,
         /*is_inline=*/false, /*is_explicit=*/false,
         /*is_attr_used=*/false, /*is_artificial=*/is_artificial);
@@ -892,6 +893,10 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
         tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag();
       }
     }
+
+    ConstString mangled_name(
+        pdb->FindMangledFunctionName(func_id).value_or(llvm::StringRef()));
+
     if (!tag_record.FieldList.isSimple()) {
       CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);
       FieldListRecord field_list;
@@ -899,15 +904,15 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
               field_list_cvt, field_list))
         llvm::consumeError(std::move(error));
       CreateMethodDecl process(index, m_clang, func_ti, function_decl,
-                               parent_opaque_ty, func_name, func_ct);
+                               parent_opaque_ty, func_name, mangled_name,
+                               func_ct);
       if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))
         llvm::consumeError(std::move(err));
     }
 
     if (!function_decl) {
       function_decl = m_clang.AddMethodToCXXRecordType(
-          parent_opaque_ty, func_name,
-          /*asm_label=*/{}, func_ct,
+          parent_opaque_ty, func_name, mangled_name, func_ct,
           /*access=*/lldb::AccessType::eAccessPublic,
           /*is_virtual=*/false, /*is_static=*/false,
           /*is_inline=*/false, /*is_explicit=*/false,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 888bd89a72625..6c6a5598689e5 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -1118,3 +1118,21 @@ size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id,
   }
   return 0;
 }
+
+llvm::StringRef lldb_private::npdb::StripCDeclPrefix(llvm::StringRef mangled) {
+  // See
+  // https://learn.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC
+  if (!mangled.starts_with('_'))
+    return mangled;
+
+  // make sure this isn't __stdcall (`_{name}@{sizeof(params)}`) or __vectorcall
+  // (`{name}@@{sizeof(params)}`).
+  size_t last_at_pos = mangled.find_last_of('@');
+  if (last_at_pos != llvm::StringRef::npos &&
+      last_at_pos < mangled.size() - 1 &&
+      llvm::all_of(mangled.slice(last_at_pos + 1, mangled.size()),
+                   llvm::isDigit))
+    return mangled;
+
+  return mangled.drop_front();
+}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
index 36e075b04f26f..e849dde124297 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -161,6 +161,18 @@ PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
 
 size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
 
+/// Strips the leading underscore of mangled __cdecl functions.
+///
+/// If the name comes from another calling convention, it is returned as-is.
+///
+/// \pre \c mangled must not be from a 64-bit environment as __cdecl names
+///     aren't mangled there.
+///
+/// \param[in] mangled A mangled symbol name
+/// \returns The stripped name if this name is a mangled __cdecl one. Otherwise,
+///     the input is returned.
+llvm::StringRef StripCDeclPrefix(llvm::StringRef mangled);
+
 } // namespace npdb
 } // namespace lldb_private
 
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 8b3d775afc163..73ae1ca631f40 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -501,7 +501,9 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
     return nullptr;
 
   PdbTypeSymId sig_id(proc.FunctionType, false);
-  Mangled mangled(proc.Name);
+  std::optional<llvm::StringRef> mangled_opt =
+      FindMangledSymbol(SegmentOffset(proc.Segment, proc.CodeOffset));
+  Mangled mangled(mangled_opt.value_or(proc.Name));
   FunctionSP func_sp = std::make_shared<Function>(
       &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
       func_type.get(), func_addr,
@@ -2662,6 +2664,46 @@ SymbolFileNativePDB::GetContextForType(TypeIndex ti) {
   return ctx;
 }
 
+std::optional<llvm::StringRef>
+SymbolFileNativePDB::FindMangledFunctionName(PdbCompilandSymId func_id) {
+  const CompilandIndexItem *cci =
+      m_index->compilands().GetCompiland(func_id.modi);
+  if (!cci)
+    return std::nullopt;
+
+  CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
+  if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
+    return std::nullopt;
+
+  ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
+  cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
+
+  return FindMangledSymbol(SegmentOffset(proc.Segment, proc.CodeOffset));
+}
+
+std::optional<llvm::StringRef>
+SymbolFileNativePDB::FindMangledSymbol(SegmentOffset so) {
+  auto symbol = m_index->publics().findByAddress(m_index->symrecords(),
+                                                 so.segment, so.offset);
+  if (!symbol)
+    return std::nullopt;
+
+  llvm::StringRef name = symbol->first.Name;
+  // "In non-64 bit environments" (on x86 in pactice), __cdecl functions get
+  // prefixed with an underscore. For compilers using LLVM, this happens in LLVM
+  // (as opposed to the compiler frontend). Because of this, DWARF doesn't
+  // contain the "full" mangled name in DW_AT_linkage_name for these functions.
+  // We strip the mangling here for compatibility with DWARF. See
+  // llvm.org/pr161676 and
+  // https://learn.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC
+  if ((symbol->first.Flags & PublicSymFlags::Function) !=
+          PublicSymFlags::None &&
+      m_index->dbi().getMachineType() == PDB_Machine::x86)
+    name = StripCDeclPrefix(name);
+
+  return name;
+}
+
 void SymbolFileNativePDB::CacheUdtDeclarations() {
   for (CVType cvt : m_index->ipi().typeArray()) {
     switch (cvt.kind()) {
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 2405f8b299339..9249d190abfd7 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -140,6 +140,12 @@ class SymbolFileNativePDB : public SymbolFileCommon {
 
   std::optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id);
 
+  /// Find the mangled name for a function
+  ///
+  /// \param id A symbol ID of a S_LPROC32/S_GPROC32 record
+  /// \returns The mangled name of the function (if available)
+  std::optional<llvm::StringRef> FindMangledFunctionName(PdbCompilandSymId id);
+
   void FindTypes(const lldb_private::TypeQuery &match,
                  lldb_private::TypeResults &results) override;
 
@@ -269,6 +275,8 @@ class SymbolFileNativePDB : public SymbolFileCommon {
   void CacheUdtDeclarations();
   llvm::Expected<Declaration> ResolveUdtDeclaration(PdbTypeSymId type_id);
 
+  std::optional<llvm::StringRef> FindMangledSymbol(SegmentOffset so);
+
   llvm::BumpPtrAllocator m_allocator;
 
   lldb::addr_t m_obj_load_address = 0;
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/break-by-function.cpp b/lldb/test/Shell/SymbolFile/NativePDB/break-by-function.cpp
index a580d574a9ca3..d4499373bb860 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/break-by-function.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/break-by-function.cpp
@@ -50,9 +50,9 @@ int main(int argc, char **argv) {
 // CHECK:      1: name = 'main', locations = 1
 // CHECK:        1.1: where = break-by-function.cpp.tmp.exe`main + {{[0-9]+}}
 // CHECK:      2: name = 'OvlGlobalFn', locations = 3
-// CHECK:        2.1: where = break-by-function.cpp.tmp.exe`OvlGlobalFn + {{[0-9]+}}
-// CHECK:        2.2: where = break-by-function.cpp.tmp.exe`OvlGlobalFn
-// CHECK:        2.3: where = break-by-function.cpp.tmp.exe`OvlGlobalFn + {{[0-9]+}}
+// CHECK:        2.1: where = break-by-function.cpp.tmp.exe`int OvlGlobalFn(int) + {{[0-9]+}}
+// CHECK:        2.2: where = break-by-function.cpp.tmp.exe`int OvlGlobalFn(int, int)
+// CHECK:        2.3: where = break-by-function.cpp.tmp.exe`int OvlGlobalFn(int, int, int) + {{[0-9]+}}
 // CHECK:      3: name = 'StaticFn', locations = 1
 // CHECK:        3.1: where = break-by-function.cpp.tmp.exe`StaticFn + {{[0-9]+}}
 // CHECK:      4: name = 'DoesntExist', locations = 0 (pending)
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/break-by-line.cpp b/lldb/test/Shell/SymbolFile/NativePDB/break-by-line.cpp
index 90ac633b01632..3d7de3275ed65 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/break-by-line.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/break-by-line.cpp
@@ -24,4 +24,4 @@ int main(int argc, char **argv) {
 // CHECK:      (lldb) target create "{{.*}}break-by-line.cpp.tmp.exe"
 // CHECK:      Current executable set to '{{.*}}break-by-line.cpp.tmp.exe'
 // CHECK:      (lldb) break set -f break-by-line.cpp -l 15
-// CHECK:      Breakpoint 1: where = break-by-line.cpp.tmp.exe`NS::NamespaceFn + {{[0-9]+}} at break-by-line.cpp:15
+// CHECK:      Breakpoint 1: where = break-by-line.cpp.tmp.exe`int NS::NamespaceFn(int) + {{[0-9]+}} at break-by-line.cpp:15
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp b/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp
new file mode 100644
index 0000000000000..569eaace1baef
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp
@@ -0,0 +1,51 @@
+// clang-format off
+// REQUIRES: lld, x86
+
+// RUN: %build --compiler=clang-cl --arch=32 --nodefaultlib --output=%t-32.exe %s
+// RUN: lldb-test symbols %t-32.exe | FileCheck --check-prefixes CHECK-32,CHECK-BOTH %s
+// RUN: %build --compiler=clang-cl --arch=64 --nodefaultlib --output=%t-64.exe %s
+// RUN: lldb-test symbols %t-64.exe | FileCheck --check-prefixes CHECK-64,CHECK-BOTH %s
+
+extern "C" {
+int FuncCCall() { return 0; }
+int __stdcall FuncStdCall() { return 0; }
+int __fastcall FuncFastCall() { return 0; }
+int __vectorcall FuncVectorCall() { return 0; }
+
+int __cdecl _underscoreCdecl() { return 0; }
+int __stdcall _underscoreStdcall() { return 0; }
+int __fastcall _underscoreFastcall() { return 0; }
+int __vectorcall _underscoreVectorcall() { return 0; }
+}
+
+int main() {
+  FuncCCall();
+  FuncStdCall();
+  FuncFastCall();
+  FuncVectorCall();
+  _underscoreCdecl();
+  _underscoreStdcall();
+  _underscoreFastcall();
+  _underscoreVectorcall();
+  return 0;
+}
+
+// CHECK-BOTH-DAG: Function{{.*}}, demangled = FuncCCall,
+// CHECK-BOTH-DAG: Function{{.*}}, demangled = FuncVectorCall@@0,
+// CHECK-BOTH-DAG: Function{{.*}}, demangled = _underscoreCdecl,
+// CHECK-BOTH-DAG: Function{{.*}}, demangled = _underscoreVectorcall@@0,
+// CHECK-BOTH-DAG: Function{{.*}}, demangled = main,
+
+// __stdcall and __fastcall aren't available on 64 bit
+
+// CHECK-32-DAG: Function{{.*}}, demangled = _FuncStdCall@0,
+// CHECK-64-DAG: Function{{.*}}, demangled = FuncStdCall,
+
+// CHECK-32-DAG: Function{{.*}}, demangled = @FuncFastCall@0,
+// CHECK-64-DAG: Function{{.*}}, demangled = FuncFastCall,
+
+// CHECK-32-DAG: Function{{.*}}, demangled = __underscoreStdcall@0,
+// CHECK-64-DAG: Function{{.*}}, demangled = _underscoreStdcall,
+
+// CHECK-32-DAG: Function{{.*}}, demangled = @_underscoreFastcall@0,
+// CHECK-64-DAG: Function{{.*}}, demangled = _underscoreFastcall,
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/disassembly.cpp b/lldb/test/Shell/SymbolFile/NativePDB/disassembly.cpp
index b3f7b098a95d9..05074aa61d32d 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/disassembly.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/disassembly.cpp
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+12>: mov    qword ptr [rsp + 0x28], rdx
 // CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+17>: mov    dword ptr [rsp + 0x24], ecx
 // CHECK:      ** 15     foo();
-// CHECK:      disassembly.cpp.tmp.exe[{{.*}}] <+21>: call   {{.*}}               ; foo at disassembly.cpp:12
+// CHECK:      disassembly.cpp.tmp.exe[{{.*}}] <+21>: call   {{.*}}               ; int foo(void) at disassembly.cpp:12
 // CHECK:      ** 16     return 0;
 // CHECK-NEXT:    17   }
 // CHECK-NEXT:    18
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp b/lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
index 3ef7a4c94c287..6204cbd34a588 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/find-functions.cpp
@@ -148,11 +148,12 @@ int main(int argc, char **argv) {
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "int (void)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "int (char)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "int (char, int, ...)"
-// FIND-OVERLOAD-BASE-DAG: Function: id = {{.*}}, name = "Class::overloaded_method"
+// FIND-OVERLOAD-BASE-DAG: Function: id = {{.*}}, name = "int Class::overloaded_method(bool)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "_Bool (void)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "_Bool (int)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "int (_Bool)"
-// FIND-OVERLOAD-BASE-DAG: Function: id = {{.*}}, name = "overloaded_method"
+// FIND-OVERLOAD-BASE-DAG: Function: id = {{.*}}, name = "char overloaded_method(void)"
+// FIND-OVERLOAD-BASE-DAG: Function: id = {{.*}}, name = "char overloaded_method(int)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "char (void)"
 // FIND-OVERLOAD-BASE-DAG: FuncType: id = {{.*}}, compiler_type = "char (int)"
 
@@ -160,6 +161,6 @@ int main(int argc, char **argv) {
 // FIND-OVERLOAD-METHOD-DAG: Function: id = {{.*}}, name = "{{.*}}Struct::overloaded_method{{.*}}"
 // FIND-OVERLOAD-METHOD-DAG: FuncType: id = {{.*}}, compiler_type = "int (void)"
 // FIND-OVERLOAD-METHOD-DAG: FuncType: id = {{.*}}, compiler_type = "int (char)"
-// FIND-OVERLOAD-METHOD-DAG: Function: id = {{.*}}, name = "Class::overloaded_method"
+// FIND-OVERLOAD-METHOD-DAG: Function: id = {{.*}}, name = "bool Class::overloaded_method(void)"
 // FIND-OVERLOAD-METHOD-DAG: FuncType: id = {{.*}}, compiler_type = "_Bool (void)"
 // FIND-OVERLOAD-METHOD-DAG: FuncType: id = {{.*}}, compiler_type = "_Bool (int)"
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp b/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp
index 44a8dc14c6158..f44a5b9dd56e2 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp
@@ -55,7 +55,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: (lldb) step
 // CHECK-NEXT: Process {{.*}} stopped
 // CHECK-NEXT: * thread #1, stop reason = step in
-// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
+// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`int Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
 // CHECK-NEXT:    6
 // CHECK-NEXT:    7
 // CHECK-NEXT:    8 int Function(int Param1, char Param2) {
@@ -71,7 +71,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: (lldb) step
 // CHECK-NEXT: Process {{.*}} stopped
 // CHECK-NEXT: * thread #1, stop reason = step in
-// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
+// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`int Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
 // CHECK-NEXT:    7
 // CHECK-NEXT:    8    int Function(int Param1, char Param2) {
 // CHECK-NEXT:    9      unsigned Local1 = Param1 + 1;
@@ -89,7 +89,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: (lldb) step
 // CHECK-NEXT: Process {{.*}} stopped
 // CHECK-NEXT: * thread #1, stop reason = step in
-// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
+// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`int Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
 // CHECK-NEXT:    8    int Function(int Param1, char Param2) {
 // CHECK-NEXT:    9      unsigned Local1 = Param1 + 1;
 // CHECK-NEXT:    10     char Local2 = Param2 + 1;
@@ -109,7 +109,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: (lldb) step
 // CHECK-NEXT: Process {{.*}} stopped
 // CHECK-NEXT: * thread #1, stop reason = step in
-// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
+// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`int Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
 // CHECK-NEXT:    9      unsigned Local1 = Param1 + 1;
 // CHECK-NEXT:    10     char Local2 = Param2 + 1;
 // CHECK-NEXT:    11     ++Local1;
@@ -129,7 +129,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: (lldb) step
 // CHECK-NEXT: Process {{.*}} stopped
 // CHECK-NEXT: * thread #1, stop reason = step in
-// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
+// CHECK-NEXT:     frame #0: {{.*}} local-variables.cpp.tmp.exe`int Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}}
 // CHECK-NEXT:    10      char Local2 = Param2 + 1;
 // CHECK-NEXT:    11     ++Local1;
 // CHECK-NEXT:    12     ++Local2;
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/stack_unwinding01.cpp b/lldb/test/Shell/SymbolFile/NativePDB/stack_unwinding01.cpp
index 596a826f4a11b..87eeebe7aa1b6 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/stack_unwinding01.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/stack_unwinding01.cpp
@@ -24,19 +24,19 @@ int main(int argc, char **argv) {
 
 // CHECK: (lldb) thread backtrace
 // CHECK-NEXT: * thread #1, stop reason = breakpoint 1.1
-// CHECK-NEXT:   * frame #0: {{.*}} stack_unwinding01.cpp.tmp.exe`Struct::simple_method(this={{.*}}, a=2, b=2) at stack_unwinding01.cpp:12
+// CHECK-NEXT:   * frame #0: {{.*}} stack_unwinding01.cpp.tmp.exe`void Struct::simple_method(this={{.*}}, a=2, b=2) at stack_unwinding01.cpp:12
 // CHECK-NEXT:     frame #1: {{.*}} stack_unwinding01.cpp.tmp.exe`main(argc={{.*}},...
[truncated]

std::optional<llvm::StringRef> mangled_opt =
FindMangledSymbol(SegmentOffset(proc.Segment, proc.CodeOffset));
if (mangled_opt)
mangled_opt = StripMangledFunctionName(*mangled_opt, proc.FunctionType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call StripMangledFunctionName from FindMangledSymbol? So we don't need to do it in two places? (then you don't need to call it from StripMangledFunctionName either)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, now we have to pass the function type to FindMangledSymbol. That's fine, since the function is only used for functions right now.

Copy link
Member

@Michael137 Michael137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@Nerixyz Nerixyz merged commit 3b14414 into llvm:main Oct 7, 2025
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 7, 2025

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building lldb at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/25340

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-shell :: SymbolFile/DWARF/x86/win-i386-line-table.s (1882 of 2332)
PASS: lldb-shell :: SymbolFile/DWARF/x86/type-unit-same-basename.cpp (1883 of 2332)
PASS: lldb-shell :: SymbolFile/DWARF/x86/simplified-template-names.cpp (1884 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/ast-functions.cpp (1885 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/blocks.s (1886 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/ast-methods.cpp (1887 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/ast-types.cpp (1888 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/bitfields.cpp (1889 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/break-by-function.cpp (1890 of 2332)
PASS: lldb-shell :: SymbolFile/NativePDB/break-by-line.cpp (1891 of 2332)
FAIL: lldb-shell :: SymbolFile/NativePDB/c-calling-conventions.cpp (1892 of 2332)
******************** TEST 'lldb-shell :: SymbolFile/NativePDB/c-calling-conventions.cpp' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 4
'/usr/bin/python3.10' /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/helper/build.py --compiler=any --arch=64 --tools-dir=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --libs-dir=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --compiler=clang-cl --arch=32 --nodefaultlib --output=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/NativePDB/Output/c-calling-conventions.cpp.tmp-32.exe /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp
# executed command: /usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/helper/build.py --compiler=any --arch=64 --tools-dir=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --libs-dir=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --compiler=clang-cl --arch=32 --nodefaultlib --output=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/NativePDB/Output/c-calling-conventions.cpp.tmp-32.exe /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp
# .---command stdout------------
# | Cleaning c-calling-conventions.ilk
# | Cleaning c-calling-conventions.cpp.tmp-32.exe-c-calling-conventions.obj
# | Cleaning c-calling-conventions.cpp.tmp-32.pdb
# | Cleaning c-calling-conventions.cpp.tmp-32.exe
# | 
# | 
# | 
# | compiling c-calling-conventions.cpp -> c-calling-conventions.cpp.tmp-32.exe-c-calling-conventions.obj
# |   STDOUT:
# | 
# | 
# | 
# | 
# | linking c-calling-conventions.cpp.tmp-32.exe-c-calling-conventions.obj -> c-calling-conventions.cpp.tmp-32.exe
# |   STDOUT:
# | 
# `-----------------------------
# RUN: at line 5
/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb-test symbols /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/NativePDB/Output/c-calling-conventions.cpp.tmp-32.exe | /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/FileCheck --check-prefixes CHECK-32,CHECK-BOTH /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp
# executed command: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb-test symbols /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/NativePDB/Output/c-calling-conventions.cpp.tmp-32.exe
# note: command had no output on stdout or stderr
# executed command: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/FileCheck --check-prefixes CHECK-32,CHECK-BOTH /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp
# .---command stderr------------
# | /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/NativePDB/c-calling-conventions.cpp:34:20: error: CHECK-BOTH-DAG: expected string not found in input
# | // CHECK-BOTH-DAG: Function{{.*}}, demangled = FuncVectorCall@@0,
# |                    ^
# | <stdin>:1:1: note: scanning from here
# | Module: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/NativePDB/Output/c-calling-conventions.cpp.tmp-32.exe
# | ^

Nerixyz added a commit that referenced this pull request Oct 7, 2025
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Oct 7, 2025
@augusto2112
Copy link
Contributor

Hi @Nerixyz, unfortunately this breaks green dragon https://ci.swift.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/34472/console

10:45:57  Failed Tests (1):
10:45:57    lldb-shell :: SymbolFile/NativePDB/c-calling-conventions.cpp

@Nerixyz
Copy link
Contributor Author

Nerixyz commented Oct 7, 2025

Hi @Nerixyz, unfortunately this breaks green dragon ci.swift.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/34472/console

10:45:57  Failed Tests (1):
10:45:57    lldb-shell :: SymbolFile/NativePDB/c-calling-conventions.cpp

Sorry, this should be fixed with #162335.

@augusto2112
Copy link
Contributor

Never mind, looks like you merged a follow up fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants