Skip to content

[Clang][Sema] Use first instantiation pattern when comparing constrained functions#1

Open
sdkrystian wants to merge 1 commit into
cppalliance:mainfrom
sdkrystian:fix-175426
Open

[Clang][Sema] Use first instantiation pattern when comparing constrained functions#1
sdkrystian wants to merge 1 commit into
cppalliance:mainfrom
sdkrystian:fix-175426

Conversation

@sdkrystian

Copy link
Copy Markdown
Member

Fixes llvm#175426

@mizvekov mizvekov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

getTemplateInstantiationPattern should dig down until it finds the pattern as written by the user, it would be pretty inconvenient if we relied on this for some cases but not others.

Can we just fix getTemplateInstantiationPattern instead?

@vinniefalco

Copy link
Copy Markdown
Member

name: Fix GH175426 Crash
overview: Fix an assertion failure in IsAtLeastAsConstrained when comparing defaulted comparison operators for local classes inside generic lambdas by properly iterating through nested member specialization chains.
todos:

  • id: fix-iteration
    content: Change if-statement to while-loop in getMoreConstrainedFunction in SemaTemplateDeduction.cpp
    status: completed
  • id: add-test
    content: Create regression test clang/test/SemaTemplate/GH175426.cpp
    status: completed

Fix GH175426: Assertion Failure in Constraint Partial Ordering

Problem Analysis

The crash occurs when:

  1. A function template contains a generic lambda
  2. The lambda contains a local class with a defaulted operator<=>
  3. The synthesized operator< triggers constraint partial ordering comparison

The failing assertion in SemaConcept.cpp:2470 checks that function declarations passed to IsAtLeastAsConstrained have TemplatedKind of either TK_NonTemplate or TK_FunctionTemplate. However, when dealing with nested instantiations (local class inside generic lambda inside function template), getTemplateInstantiationPattern(false) only traverses one level of the member specialization chain.

Root Cause

In SemaTemplateDeduction.cpp getMoreConstrainedFunction:

FunctionDecl *F1 = FD1;
if (FunctionDecl *P = FD1->getTemplateInstantiationPattern(false))
  F1 = P;

This only goes one level back. For a local class inside a generic lambda, the instantiation chain may have multiple levels:

  • Instantiated comparison operator -> local class pattern's operator -> ...

The pattern retrieved may still be TK_MemberSpecialization, causing the assertion to fail.

Compare to SemaLambda.cpp getPatternFunctionDecl which correctly iterates:

if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization) {
  while (FD->getInstantiatedFromMemberFunction())
    FD = FD->getInstantiatedFromMemberFunction();
  return FD;
}

Solution

Modify getMoreConstrainedFunction to iterate through all levels of the instantiation chain by using a while loop instead of a single if:

FunctionDecl *F1 = FD1;
while (FunctionDecl *P = F1->getTemplateInstantiationPattern(false))
  F1 = P;

FunctionDecl *F2 = FD2;
while (FunctionDecl *P = F2->getTemplateInstantiationPattern(false))
  F2 = P;

Files to Modify

Test Case

The test should verify no crash occurs and the expected error (missing <compare> header) is properly emitted:

// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s

template <typename T1> auto fwd2(const T1 &t1) {
  return [](auto &&...ts1) {
    struct LocalType {
      int data;
      auto operator<=>(const LocalType &other) const = default; // expected-error {{cannot default}}
    };
    LocalType x{42}, y{42};
    static_assert(noexcept(x < y), "Noexcept check failed");
  }();
}

int main() { return fwd2(1); }

@sdkrystian

Copy link
Copy Markdown
Member Author

@mizvekov

That's a good point. Let me examine FunctionDecl::getTemplateInstantiationPattern to understand why it doesn't iterate through the full chain like VarDecl::getTemplateInstantiationPattern does.

[2 tools called]

You're right. Looking at the two implementations:

VarDecl::getTemplateInstantiationPattern iterates through the chain:

  if (MemberSpecializationInfo *MSInfo = VD->getMemberSpecializationInfo()) {
    if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
      VD = VD->getInstantiatedFromStaticDataMember();
      while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
        VD = NewVD;
    }
  }

FunctionDecl::getTemplateInstantiationPattern only goes one level:

  if (MemberSpecializationInfo *Info = FD->getMemberSpecializationInfo()) {
    if (ForDefinition &&
        !clang::isTemplateInstantiation(Info->getTemplateSpecializationKind()))
      return nullptr;
    return getDefinitionOrSelf(cast<FunctionDecl>(Info->getInstantiatedFrom()));
  }

This inconsistency does seem like an oversight. The fix in FunctionDecl::getTemplateInstantiationPattern would be to add a similar iteration loop:

if (MemberSpecializationInfo *Info = FD->getMemberSpecializationInfo()) {
  if (ForDefinition &&
      !clang::isTemplateInstantiation(Info->getTemplateSpecializationKind()))
    return nullptr;
  FunctionDecl *Result = FD->getInstantiatedFromMemberFunction();
  while (FunctionDecl *Next = Result->getInstantiatedFromMemberFunction())
    Result = Next;
  return getDefinitionOrSelf(Result);
}

This would be a more principled fix because:

  1. It matches the behavior of VarDecl::getTemplateInstantiationPattern
  2. All callers of getTemplateInstantiationPattern would benefit from consistent behavior
  3. It avoids having to add iteration loops in multiple call sites like getMoreConstrainedFunction

Would you like to switch to Agent mode so I can implement this fix in clang/lib/AST/Decl.cpp instead?

sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…#185473)

This patch extracts the `msg` value of the `failwithmessage` error and
uses it as the stop reason if the MSVC Runtime fails while debugging.

# Before
```
lldb.exe C:\Users\charleszablit\Developer\testing\uninit.exe -b -o 'r'
(lldb) target create "C:\\Users\\charleszablit\\Developer\\testing\\uninit.exe"
Current executable set to 'C:\Users\charleszablit\Developer\testing\uninit.exe' (x86_64).
(lldb) r
Process 9400 launched: 'C:\Users\charleszablit\Developer\testing\uninit.exe' (x86_64)
Process 9400 stopped
* thread #1, stop reason = Exception 0x80000003 encountered at address 0x7ff96516c96a
       frame #0: 0x00007ff77efe20ba uninit.exe`failwithmessage(retaddr=0x00007ff77efe150f, crttype=1, errnum=3, msg="The variable 'x' is being used without being initialized.") at error.cpp:210
```

# After
```
lldb.exe C:\Users\charleszablit\Developer\testing\uninit.exe -b -o 'r'
(lldb) target create "C:\\Users\\charleszablit\\Developer\\testing\\uninit.exe"
Current executable set to 'C:\Users\charleszablit\Developer\testing\uninit.exe' (x86_64).
(lldb) r
Process 9400 launched: 'C:\Users\charleszablit\Developer\testing\uninit.exe' (x86_64)
Process 9400 stopped
* thread #1, stop reason = Run-time check failure: The variable 'x' is being used without being initialized.
       frame #0: 0x00007ff77efe20ba uninit.exe`failwithmessage(retaddr=0x00007ff77efe150f, crttype=1, errnum=3, msg="The variable 'x' is being used without being initialized.") at error.cpp:210
```


fix llvm#184990.

rdar://172103284
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…e edge case (llvm#188590)

llvm#186966 was reverted because
the test case triggered a use-of-uninitialized-memory
(https://lab.llvm.org/buildbot/#/builders/94/builds/16379), due to the
include directive omitting a trailing newline. This patch adds a minor
fix to avoid the use-of-uninitialized-memory, and deliberately re-adds
the test case sans trailing newline for regression testing.

MSan report prior to this fix:
```
@@@BUILD_STEP sanitizer logs: stage2/msan_track_origins check@@@
==clang-scan-deps==616960==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x5555599c3300 in isAnnotation /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/include/clang/Lex/Token.h:131:38
    #1 0x5555599c3300 in setLength /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/include/clang/Lex/Token.h:152:13
    #2 0x5555599c3300 in clang::Lexer::FormTokenWithChars(clang::Token&, char const*, clang::tok::TokenKind) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/include/clang/Lex/Lexer.h:644:12
    #3 0x5555599cf895 in clang::Lexer::LexEndOfFile(clang::Token&, char const*) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Lex/Lexer.cpp:3166:5
    #4 0x555559bb229b in clang::Preprocessor::Lex(clang::Token&) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Lex/Preprocessor.cpp:916:11
    #5 0x555559aa5365 in __invoke<void (clang::Preprocessor::*&)(clang::Token &), clang::Preprocessor *, clang::Token &> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/libcxx_install_msan_track_origins/include/c++/v1/__type_traits/invoke.h:90:27
    #6 0x555559aa5365 in invoke<void (clang::Preprocessor::*&)(clang::Token &), clang::Preprocessor *, clang::Token &> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/libcxx_install_msan_track_origins/include/c++/v1/__functional/invoke.h:29:10
    #7 0x555559aa5365 in operator()<void (clang::Preprocessor::*)(clang::Token &)> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Lex/PPDirectives.cpp:470:5
    llvm#8 0x555559aa5365 in clang::Preprocessor::CheckEndOfDirective(llvm::StringRef, bool, llvm::SmallVectorImpl<clang::Token>*) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Lex/PPDirectives.cpp:478:5
    llvm#9 0x555559ab96b5 in clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*) /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/clang/lib/Lex/PPDirectives.cpp:2205:7
    ...
```
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
Running gcc test c-c++-common/tsan/tls_race.c on s390 we get:

ThreadSanitizer: CHECK failed: tsan_platform_linux.cpp:618 "((thr_beg))
>= ((tls_addr))" (0x3ffaa35e140, 0x3ffaa35e250) (tid=2419930)
#0 __tsan::CheckUnwind() /devel/src/libsanitizer/tsan/tsan_rtl.cpp:696
(libtsan.so.2+0x91b57)
#1 __sanitizer::CheckFailed(char const*, int, char const*, unsigned long
long, unsigned long long)
/devel/src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:86
(libtsan.so.2+0xd211b)
#2 __tsan::ImitateTlsWrite(__tsan::ThreadState*, unsigned long, unsigned
long) /devel/src/libsanitizer/tsan/tsan_platform_linux.cpp:618
(libtsan.so.2+0x8faa3)
#3 __tsan::ThreadStart(__tsan::ThreadState*, unsigned int, unsigned long
long, __sanitizer::ThreadType)
/devel/src/libsanitizer/tsan/tsan_rtl_thread.cpp:225
(libtsan.so.2+0xaadb5)
#4 __tsan_thread_start_func
/devel/src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1065
(libtsan.so.2+0x3d34d)
#5 start_thread <null> (libc.so.6+0xae70d) (BuildId:
d3b08de1b543c2d15d419bf861b3c2e4c01ac75b)
#6 thread_start <null> (libc.so.6+0x12d2ff) (BuildId:
d3b08de1b543c2d15d419bf861b3c2e4c01ac75b)

In order to determine the static TLS blocks in GetStaticTlsBoundary we
iterate over the modules and try to find the largest range without a
gap. Here we might have that modules are spaced exactly by the
alignment. For example, for the failing test we have:

(gdb) p/x ranges.data_[0]
$1 = {begin = 0x3fff7f9e6b8, end = 0x3fff7f9e740, align = 0x8, tls_modid
= 0x3} (gdb) p/x ranges.data_[1]
$2 = {begin = 0x3fff7f9e740, end = 0x3fff7f9eed0, align = 0x40,
tls_modid = 0x2} (gdb) p/x ranges.data_[2]
$3 = {begin = 0x3fff7f9eed8, end = 0x3fff7f9eef8, align = 0x8, tls_modid
= 0x4} (gdb) p/x ranges.data_[3]
$4 = {begin = 0x3fff7f9eefc, end = 0x3fff7f9ef00, align = 0x4, tls_modid
= 0x1}

where ranges[3].begin == ranges[2].end + ranges[3].align holds. Since in
the loop a strict inequality test is used we compute the wrong address

(gdb) p/x *addr
$5 = 0x3fff7f9eefc

whereas 0x3fff7f9e6b8 is expected which is why we bail out in the
subsequent.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…8271)

Example:

    int foo(int a, int b) { return a - 1 + ~b; }

Before, on AArch64:

    mvn w8, w1
    add w8, w0, w8
    sub w0, w8, #1

After (matches gcc):

    sub w0, w0, w1
    sub w0, w0, #2

Proof: https://alive2.llvm.org/ce/z/g_bV01
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…bols add' (llvm#188377)

Context: 
lldb might crash when running to a debuggee crashing state and do a
target symbols add command.
Backtrace: 
```
 #0 0x000055ca6790dc65 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:848:11
 #1 0x000055ca6790e434 PrintStackTraceSignalHandler(void*) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:931:1
 #2 0x000055ca6790b839 llvm::sys::RunSignalHandlers() /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Signals.cpp:104:5
 #3 0x000055ca6790ff6b SignalHandler(int, siginfo_t*, void*) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:430:38
 #4 0x00007fe9e5e44560 __restore_rt /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/signal/../sysdeps/unix/sysv/linux/libc_sigaction.c:13:0
 #5 0x00007fe9e5f25649 syscall /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/misc/../sysdeps/unix/sysv/linux/x86_64/syscall.S:38:0
 #6 0x00007fe9ec649170 SignalHandler(int, siginfo_t*, void*) /home/hyubo/osmeta/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:429:7
 #7 0x00007fe9e5e44560 __restore_rt /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/signal/../sysdeps/unix/sysv/linux/libc_sigaction.c:13:0
 llvm#8 0x00007fe9ebb77bf0 lldb_private::operator<(lldb_private::StackID const&, lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/StackID.cpp:99:16
 llvm#9 0x00007fe9ebb6863d CompareStackID(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/StackFrameList.cpp:683:3
llvm#10 0x00007fe9ebb6d049 bool __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>::operator()<__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const>(__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const&) /mnt/gvfs/third-party2/libgcc/d1129753c8361ac8e9453c0f4291337a4507ebe6/11.x/platform010/5684a5a/include/c++/11.x/bits/predefined_ops.h:196:4
llvm#11 0x00007fe9ebb6cefe __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>> std::__lower_bound<__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>>(__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const&, __gnu_cxx::__ops::_Iter_comp_val<bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>) /mnt/gvfs/third-party2/libgcc/d1129753c8361ac8e9453c0f4291337a4507ebe6/11.x/platform010/5684a5a/include/c++/11.x/bits/stl_algobase.h:1464:8
llvm#12 0x00007fe9ebb6cdfc __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>> std::lower_bound<__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>(__gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, __gnu_cxx::__normal_iterator<std::shared_ptr<lldb_private::StackFrame>*, std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>>, lldb_private::StackID const&, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)) /mnt/gvfs/third-party2/libgcc/d1129753c8361ac8e9453c0f4291337a4507ebe6/11.x/platform010/5684a5a/include/c++/11.x/bits/stl_algo.h:2062:14
llvm#13 0x00007fe9ebb685fa auto llvm::lower_bound<std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>&, lldb_private::StackID const&, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)>(std::vector<std::shared_ptr<lldb_private::StackFrame>, std::allocator<std::shared_ptr<lldb_private::StackFrame>>>&, lldb_private::StackID const&, bool (*)(std::shared_ptr<lldb_private::StackFrame> const&, lldb_private::StackID const&)) /home/hyubo/osmeta/external/llvm-project/llvm/include/llvm/ADT/STLExtras.h:2001:10
llvm#14 0x00007fe9ebb68441 lldb_private::StackFrameList::GetFrameWithStackID(lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/StackFrameList.cpp:697:11
llvm#15 0x00007fe9ebbee395 lldb_private::Thread::GetFrameWithStackID(lldb_private::StackID const&) /home/hyubo/osmeta/external/llvm-project/lldb/include/lldb/Target/Thread.h:459:7
llvm#16 0x00007fe9ebac7cf7 lldb_private::ExecutionContextRef::GetFrameSP() const /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/ExecutionContext.cpp:643:25
llvm#17 0x00007fe9ebac80e1 lldb_private::GetStoppedExecutionContext(lldb_private::ExecutionContextRef const*) /home/hyubo/osmeta/external/llvm-project/lldb/source/Target/ExecutionContext.cpp:164:34
llvm#18 0x00007fe9eb8903fa lldb_private::Statusline::Redraw(std::optional<lldb_private::ExecutionContextRef>) /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/Statusline.cpp:139:7
llvm#19 0x00007fe9eb7ac8be lldb_private::Debugger::RedrawStatusline(std::optional<lldb_private::ExecutionContextRef>) /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/Debugger.cpp:1233:3
llvm#20 0x00007fe9eb804d1e lldb_private::IOHandlerEditline::RedrawCallback() /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:446:3
llvm#21 0x00007fe9eb80aa81 lldb_private::IOHandlerEditline::IOHandlerEditline(lldb_private::Debugger&, lldb_private::IOHandler::Type, std::shared_ptr<lldb_private::File> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, unsigned int, char const*, llvm::StringRef, llvm::StringRef, bool, bool, unsigned int, lldb_private::IOHandlerDelegate&)::$_2::operator()() const /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:262:73
llvm#22 0x00007fe9eb80aa5d void llvm::detail::UniqueFunctionBase<void>::CallImpl<lldb_private::IOHandlerEditline::IOHandlerEditline(lldb_private::Debugger&, lldb_private::IOHandler::Type, std::shared_ptr<lldb_private::File> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, std::shared_ptr<lldb_private::LockableStreamFile> const&, unsigned int, char const*, llvm::StringRef, llvm::StringRef, bool, bool, unsigned int, lldb_private::IOHandlerDelegate&)::$_2>(void*) /home/hyubo/osmeta/external/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h:213:5
llvm#23 0x00007fe9eb93bfbf llvm::unique_function<void ()>::operator()() /home/hyubo/osmeta/external/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h:365:5
llvm#24 0x00007fe9eb93bb80 lldb_private::Editline::GetCharacter(wchar_t*) /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:0:5
llvm#25 0x00007fe9eb941a18 lldb_private::Editline::ConfigureEditor(bool)::$_0::operator()(editline*, wchar_t*) const /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:1287:5
llvm#26 0x00007fe9eb9419e2 lldb_private::Editline::ConfigureEditor(bool)::$_0::__invoke(editline*, wchar_t*) /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:1286:27
llvm#27 0x00007fe9f3384e26 el_getc /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:439:14
llvm#28 0x00007fe9f3384e26 el_getc /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:400:1
llvm#29 0x00007fe9f3384f90 read_getcmd /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:247:14
llvm#30 0x00007fe9f3384f90 el_gets /home/engshare/third-party2/libedit/3.1/src/libedit/src/read.c:586:14
llvm#31 0x00007fe9eb9409f3 lldb_private::Editline::GetLine(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Host/common/Editline.cpp:1636:16
llvm#32 0x00007fe9eb8044d7 lldb_private::IOHandlerEditline::GetLine(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:339:5
llvm#33 0x00007fe9eb805609 lldb_private::IOHandlerEditline::Run() /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/IOHandler.cpp:600:11
llvm#34 0x00007fe9eb7b214c lldb_private::Debugger::RunIOHandlers() /home/hyubo/osmeta/external/llvm-project/lldb/source/Core/Debugger.cpp:1280:16
llvm#35 0x00007fe9eb98f00f lldb_private::CommandInterpreter::RunCommandInterpreter(lldb_private::CommandInterpreterRunOptions&) /home/hyubo/osmeta/external/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp:3620:16
llvm#36 0x00007fe9eb4f0e09 lldb::SBDebugger::RunCommandInterpreter(bool, bool) /home/hyubo/osmeta/external/llvm-project/lldb/source/API/SBDebugger.cpp:1234:42
llvm#37 0x000055ca6788d6b0 Driver::MainLoop() /home/hyubo/osmeta/external/llvm-project/lldb/tools/driver/Driver.cpp:677:3
llvm#38 0x000055ca6788e226 main /home/hyubo/osmeta/external/llvm-project/lldb/tools/driver/Driver.cpp:887:17
llvm#39 0x00007fe9e5e2c657 __libc_start_call_main /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
llvm#40 0x00007fe9e5e2c718 call_init /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../csu/libc-start.c:128:20
llvm#41 0x00007fe9e5e2c718 __libc_start_main@GLIBC_2.2.5 /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../csu/libc-start.c:379:5
llvm#42 0x000055ca67889a11 _start /home/engshare/third-party2/glibc/2.34/src/glibc-2.34/csu/../sysdeps/x86_64/start.S:118:0
Segmentation fault (core dumped)
```

When `target symbols add` is run, `Symtab::AddSymbol()` can reallocate
the underlying `std::vector<Symbol>` and resize it, invalidating all
existing Symbol* pointers. While `Process::Flush()` clears stale stack
frames, the statusline caches its own `ExecutionContextRef` containing a
`StackID` with a `SymbolContextScope*` (which can be a `Symbol*`). This
cached reference is not cleared by `Process::Flush()`, so the next
statusline redraw accesses a dangling pointer and crashes.

Fix this by adding `Statusline::Flush()` which clears the cached frame,
`Debugger::Flush()` which forwards to it under the statusline mutex, and
calling `Debugger::Flush()` from `Process::Flush()` so that all flush
paths (symbol add, exec, module load) also invalidate the statusline's
stale state.

After this fix, lldb is not crashing anymore, new symbols from a symbol
file are correctly loaded

---------

Co-authored-by: George Hu <georgehuyubo@gmail.com>
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
When Control Flow Integrity (CFI) is enabled, jump tables are used to
redirect indirect calls. Previously, these jump table entries lacked
debug information, making it difficult for profilers and debuggers to
attribute execution time correctly.

Now stack trace, when stopped on jump table entry will looks like this:
```
#0: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0
#1: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0
#2: .cfi.jumptable.81 at sanitizer/ubsan_interface.h:0:0
```
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…93670)

When Control Flow Integrity (CFI) is enabled, jump tables are used to
redirect indirect calls. Previously, these jump table entries lacked
debug information, making it difficult for profilers and debuggers to
attribute execution time correctly.

Now stack trace, when stopped on jump table entry will looks like this:
```
#0: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0
#1: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0
#2: .cfi.jumptable.81 at sanitizer/ubsan_interface.h:0:0
```

This is reland of llvm#192736, reverted with llvm#193663.
This version don't update debug info for "Cross-DSO CFI" mode.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
llvm#184115)

In this change I'm extending the "memory region" command to show users
the
overlay permissions that a protection key refers to, and the result of
applying that overlay to the page table permissions.

For example, protection key 0 refers to Perm0 in the por register.
```
(lldb) register read por 
             Perm0 = Read, Write, Execute
```
This is the default key, so many regions use it. 
```
(lldb) memory region --all
<...>
[0x000ffffff7db0000-0x000ffffff7f40000) r-x /usr/lib/aarch64-linux-gnu/libc.so.6 PT_LOAD[0]
protection key: 0 (rwx, effective: r-x)
```
Protection keys can only change what was already enabled in the 
page table. So we start with read and execute. Then a read/write/execute
overlay
is applied. We cannot add write, so the result is read and execute.

Here's an example of its use with a real crash (output edited):
```
(lldb) c
* thread #1, name = 'test.o', stop reason = signal SIGSEGV: failed protection key checks (fault address=0xffffff7d60000)
-> 106    read_only_page[0] = '?';
(lldb) memory region 0xffffff7d60000
[0x000ffffff7d60000-0x000ffffff7d70000) rw- 
protection key: 6 (r--, effective: r--)
(lldb) register read por 
             Perm6 = Read
```
The calculation of permissions is implemented by a new ABI method.
It's in ABI for 2 reasons:
* These overlays are usually in a register (X86 and AArch64 are)
  and that register name is architecture specific.
* The way the overlay values apply may differ between architecture.
  AArch64 treats a set bit as adding a permission, but some may 
  treat it as removing.

Technically this is dependent on operating system and architecture.
However, so are the methods for removing non-address bits, and those
are in ABI too.

To test this I have changed the allocations in the test program
to use read+execute permissions by default. With read+write+execute
I could not observe that the overlay only changes enabled permissions.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
We did not initialize the out parameters in llvm#192347, causing the
"sanitizer-x86_64-linux-fast" bot to complain with:

```
SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1525:63 in compileModuleImpl(clang::CompilerInstance&, clang::SourceLocation, clang::SourceLocation, clang::Module*, clang::ModuleFileName)
Exiting
==clang==3084515==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x586360f7a604 in compileModuleImpl(clang::CompilerInstance&, clang::SourceLocation, clang::SourceLocation, clang::Module*, clang::ModuleFileName) /home/b/sanitizer-x86_64-linux-fast/build/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1525:63
    #1 <...>
```

This PR should fix that.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…lvm#141480)

When a vector integer-to-float conversion is followed by a multiply with a
reciprocal power-of-two constant, we can fold both operations into a single
SCVTF or UCVTF instruction with a fixed-point shift operand.

For example, `fmul(sitofp(v2i32 x), <0.5, 0.5>)` becomes `scvtf.2s v0, v0, #1`.

This is a reworked version with several improvements over the original
submission:
- Rewrite the C++ operand matcher to share implementation with the existing
    `SelectCVTFixedPointVec` (MOVIshift, FMOV, and DUP handling with correct
    truncation for f16)
- Add `uitofp`/`ucvtf` patterns via a `CVTFRecipPat` multiclass
- Add full GlobalISel support (`GIComplexOperandMatcher` + renderer)

Supported vector types: `v2f32`, `v4f32`, `v2f64`, `v4f16`, `v8f16`.

Fixes llvm#94909
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…h the current thread is stopped (llvm#194272)

Adds `.` as a new `breakpt-id` syntax. Users can specify `.` to mean the breakpoint
location(s) that caused the current thread to stop.

I selected `.` to mean the current breakpoint locations for two reasons. In a shells,
period means <ins>current</ins> directory. In prose, a period is a <ins>stop</ins>.

My workflow often starts with multiple breakpoint locations, such as with regex
breakpoints, or basename breakpoints for overloaded/overridden names. As locations are
hit, I realize which locations are no longer needed. This new syntax makes it quick and
easy to disable the currently stopped location(s).

Another use case for this is to quickly repeat commands for the current location:

``` break com add -o 'p someVar' .  ```

Usage example:

``` (lldb) b main.c:2 Process 47071 stopped * thread #1, queue =
'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: ... main`main at main.c:2:3
   1    int main() {
-> 2      return 0;
   3    }
Target 0: (main) stopped.  (lldb) breakpoint disable .  1 breakpoints disabled.  (lldb)
breakpoint list Current breakpoints: 1: file = 'main.c', line = 2, exact_match = 0,
locations = 1
  1.1: where = main`main + 12 at main.c:2:3, address = ..., hit count = 1  Options:
  disabled
```

rdar://73047170

Assisted-by: claude
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
[LowerTypeTests] Add debug info to jump table entries (llvm#192736)
    
When Control Flow Integrity (CFI) is enabled, jump tables are used to
redirect indirect calls. Previously, these jump table entries lacked
debug information, making it difficult for profilers and debuggers to
attribute execution time correctly.

Now stack trace, when stopped on jump table entry will looks like this:
```
#0: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0
#1: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0
```

Following up on previous attempts llvm#192736 and llvm#193670, this PR is
essentially llvm#192736 but with the `(.cfi_jt)` and
`__ubsan_check_cfi_icall_jt`
frames swapped. While the specific order of `__ubsan_check_cfi_icall_jt`
isn't strictly necessary, swapping them helps maintain existing
diagnostics
behavior.
Additionally, the diagnostics must remove `ubsan_interface.h` to allow
for a fallback to printing the module name.
See "Commits" tab for details.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…input" (llvm#195551)

Reverts llvm#190863 due to buildbot breakage e.g.,
https://lab.llvm.org/buildbot/#/builders/52/builds/16951

```
Failed Tests (1):
  LLVM :: tools/llvm-profgen/filter-build-id.test
```
```
==llvm-profgen==3809550==ERROR: AddressSanitizer: container-overflow on address 0x6e80441e1762 at pc 0x6216c3f2cdce bp 0x7fff3c3ddf60 sp 0x7fff3c3dd710
READ of size 8 at 0x6e80441e1762 thread T0
    #0 0x6216c3f2cdcd in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:848:7
    #1 0x6216c3f2d25c in bcmp /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:894:10
    #2 0x6216c400b836 in operator== /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/include/llvm/ADT/StringRef.h:914:10
    #3 0x6216c400b836 in operator!= /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/include/llvm/ADT/StringRef.h:917:69
    #4 0x6216c400b836 in llvm::sampleprof::PerfScriptReader::extractCallstack(llvm::sampleprof::TraceStream&, llvm::SmallVectorImpl<unsigned long>&) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:801:36
    #5 0x6216c400d37a in llvm::sampleprof::HybridPerfReader::parseSample(llvm::sampleprof::TraceStream&, unsigned long) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:881:8
    #6 0x6216c40150d8 in parseSample /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1118:3
    #7 0x6216c40150d8 in llvm::sampleprof::PerfScriptReader::parseEventOrSample(llvm::sampleprof::TraceStream&) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1201:5
    llvm#8 0x6216c401539a in llvm::sampleprof::PerfScriptReader::parseAndAggregateTrace() /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1210:5
    llvm#9 0x6216c4018c88 in llvm::sampleprof::PerfScriptReader::parsePerfTraces() /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1457:3
    llvm#10 0x6216c3ff2c7a in main /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/llvm-profgen.cpp:229:19
    llvm#11 0x72404502a8c0  (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a8c0) (BuildId: ae327f26c123ea1374623c41e676a4bf00e5c1cb)
    llvm#12 0x72404502a9d7 in __libc_start_main (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a9d7) (BuildId: ae327f26c123ea1374623c41e676a4bf00e5c1cb)
    llvm#13 0x6216c3f0f3d4 in _start (/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-profgen+0x2f083d4)
0x6e80441e1762 is located 18 bytes inside of 48-byte region [0x6e80441e1750,0x6e80441e1780)
allocated by thread T0 here:
    #0 0x6216c3feab0d in operator new(unsigned long) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:109:35
    #1 0x724045511c07 in __libcpp_allocate<char> /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/__new/allocate.h:42:28
    #2 0x724045511c07 in allocate /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/__memory/allocator.h:92:14
    #3 0x724045511c07 in allocate_at_least /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/__memory/allocator.h:99:13
    #4 0x724045511c07 in allocate_at_least<std::__1::allocator<char> > /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/__memory/allocator_traits.h:340:22
    #5 0x724045511c07 in __allocate_at_least<std::__1::allocator<char> > /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/__memory/allocate_at_least.h:36:16
    #6 0x724045511c07 in __allocate_long_buffer /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/string:2259:21
    #7 0x724045511c07 in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::__grow_by(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/libcxx/include/string:2769:25
    llvm#8 0x6216c401d90a in __grow_by_without_replace /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_install_asan/include/c++/v1/string:2795:3
    llvm#9 0x6216c401d90a in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>& std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::append[abi:sqn230000]<char const*, 0>(char const*, char const*) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_install_asan/include/c++/v1/string:1431:9
    llvm#10 0x6216c401d1a6 in std::__1::basic_istream<char, std::__1::char_traits<char>>& std::__1::getline[abi:sqn230000]<char, std::__1::char_traits<char>, std::__1::allocator<char>>(std::__1::basic_istream<char, std::__1::char_traits<char>>&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&, char) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_install_asan/include/c++/v1/istream:1309:15
    llvm#11 0x6216c4014a76 in getline<char, std::__1::char_traits<char>, std::__1::allocator<char> > /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/libcxx_install_asan/include/c++/v1/istream:1343:10
    llvm#12 0x6216c4014a76 in advance /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.h:52:10
    llvm#13 0x6216c4014a76 in llvm::sampleprof::PerfScriptReader::parseAggregatedCount(llvm::sampleprof::TraceStream&) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1110:13
    llvm#14 0x6216c4015095 in parseSample /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1116:20
    llvm#15 0x6216c4015095 in llvm::sampleprof::PerfScriptReader::parseEventOrSample(llvm::sampleprof::TraceStream&) /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1201:5
    llvm#16 0x6216c401539a in llvm::sampleprof::PerfScriptReader::parseAndAggregateTrace() /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1210:5
    llvm#17 0x6216c4018c88 in llvm::sampleprof::PerfScriptReader::parsePerfTraces() /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/PerfReader.cpp:1457:3
    llvm#18 0x6216c3ff2c7a in main /home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/llvm/tools/llvm-profgen/llvm-profgen.cpp:229:19
    llvm#19 0x72404502a8c0  (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a8c0) (BuildId: ae327f26c123ea1374623c41e676a4bf00e5c1cb)
    llvm#20 0x72404502a9d7 in __libc_start_main (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a9d7) (BuildId: ae327f26c123ea1374623c41e676a4bf00e5c1cb)
    llvm#21 0x6216c3f0f3d4 in _start (/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-profgen+0x2f083d4)
```
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…ExtFree (llvm#195285)

When a narrow load i8 or i16 is frozen and its value crosses a basic
block, `getCopyToRegs` emits `any_extend` instead of `zero_extend`
because `isZExtFree` can't see through the `ISD::FREEZE` node.

Example: https://godbolt.org/z/MYvjq8vPM contains an redundant `and w11,
w11, 0xff`
```
        ldrb    w11, [x10], #1
        cmp     w11, llvm#32
        b.lo    .LBB0_1
        and     w11, w11, #0xff
```

Fix this by passing the incoming node to the freeze to `isZExtFree`
instead.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
llvm#183506 revealed a pre-existing
use-after-scope in createInstrInfo (MSan bot:
https://lab.llvm.org/buildbot/#/builders/164/builds/21562 [*]).

This patch fixes the issue by changing the stack-allocated
AArch64Subtarget (which goes out of scope once createInstrInfo()
returns) into heap-allocated, allowing it to be safely stored in the
returned AArch64InstrInfo.

-----

[*] WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x55555666fabd in
llvm::AArch64InstrInfo::getInstSizeInBytes(llvm::MachineInstr const&)
const
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp:247:5
...

/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/unittests/Target/AArch64/InstSizes.cpp:85:3
llvm#9 0x555556508559 in InstSizes_MOVaddrTagged_Test::TestBody()
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/unittests/Target/AArch64/InstSizes.cpp:301:3
...

  Member fields were destroyed
#0 0x555556498a1d in __sanitizer_dtor_callback_fields
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp:1074:5
#1 0x5555564fbda6 in ~Triple
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/include/llvm/TargetParser/Triple.h:348:12
#2 0x5555564fbda6 in ~Triple
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/include/llvm/TargetParser/Triple.h:47:7
#3 0x5555564fbda6 in llvm::AArch64Subtarget::~AArch64Subtarget()
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/lib/Target/AArch64/AArch64Subtarget.h:38:7
#4 0x555556503396 in (anonymous
namespace)::createInstrInfo(llvm::TargetMachine*)
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/unittests/Target/AArch64/InstSizes.cpp:38:1
#5 0x5555565084cb in InstSizes_MOVaddrTagged_Test::TestBody()
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/unittests/Target/AArch64/InstSizes.cpp:299:42
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…198548)

When an MCP client disconnects (EOF), `IOTransport::OnRead` called
`handler.OnClosed()` before resetting `m_read_handle`. The MCP server's
`OnClosed` handler erases the client from `m_instances`, destroying both
  the transport (`this`) and the binder (`handler`). The subsequent
`m_read_handle.reset()` then accessed the destroyed transport's member,
  causing a use-after-free (SIGSEGV).

* thread #1, stop reason = signal SIGSEGV: address not mapped to object
(fault address=0x28)
* frame #0: 0x00007ff5d4d5afda
liblldb.so.23.2`lldb_private::transport::IOTransport<lldb_protocol::mcp::ProtocolDescriptor>::OnRead(lldb_private::MainLoopBase&,
lldb_private::transport::JSONTransport<lldb_protocol::mcp::ProtocolDescriptor>::MessageHandler&)
+ 1274
frame #1: 0x00007ff5d1140ad8
liblldb.so.23.0`lldb_private::MainLoopPosix::Run() + 408
frame #2: 0x00007ff5d1760c1c
liblldb.so.23.0`std::thread::_State_impl<std::thre

  Fix by resetting the read handle before calling `OnClosed()`, so no
  transport members are accessed after the handler potentially destroys
  the transport.

Then when the scope is left, the destructor is called for the new
read_handle local variable and it is cleaned up.

New unit tests added that fail without this change. With the change, the
custom 'ai' script (allows end user locally to communicate lldb context
to agent backend via a spun up MCP server: "protocol-server start MCP
listen://localhost:{port}") now successfully concludes without this
crash

Assisted with: claude
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
Fix llvm#201615.

Fix the issue that non atomic operations race in waiting queue, which
causes missed futex wakeup signals.

Confirmed by TSAN:

```
==================
WARNING: ThreadSanitizer: data race (pid=388518)
  Write of size 4 at 0x7ffd21cf98e4 by thread T23:
    #0 __llvm_libc_23_0_0_git::RawRwLock::notify_pending_threads() ./libc/src/__support/threads/raw_rwlock.h:443:44
    #1 __llvm_libc_23_0_0_git::RawRwLock::unlock() ./libc/src/__support/threads/raw_rwlock.h:520:5
    #2 randomized_thread_operation(SharedData*) ./libc/test/integration/src/__support/threads/tsan_full_rwlock.cpp:104:18
    #3 thread_runner(void*) ./libc/test/integration/src/__support/threads/tsan_full_rwlock.cpp:148:5

  Previous atomic read of size 4 at 0x7ffd21cf98e4 by thread T4:
    #0 __llvm_libc_23_0_0_git::cpp::Atomic<unsigned int>::load(...) ./libc/src/__support/CPP/atomic.h:115:5
    #1 __llvm_libc_23_0_0_git::Futex::wait(...) ./libc/src/__support/threads/linux/futex_utils.h:43:17
    #2 __llvm_libc_23_0_0_git::cpp::expected<int, int> __llvm_libc_23_0_0_git::rwlock::WaitingQueue::wait<Role::Reader>(...) ./libc/src/__support/threads/raw_rwlock.h:101:35
    #3 __llvm_libc_23_0_0_git::rwlock::LockResult __llvm_libc_23_0_0_git::RawRwLock::lock_slow<Role::Reader>(...) ./libc/src/__support/threads/raw_rwlock.h:402:34
    #4 __llvm_libc_23_0_0_git::RawRwLock::read_lock(...) ./libc/src/__support/threads/raw_rwlock.h:485:12
    #5 randomized_thread_operation(SharedData*) ./libc/test/integration/src/__support/threads/tsan_full_rwlock.cpp:79:16
    #6 thread_runner(void*) ./libc/test/integration/src/__support/threads/tsan_full_rwlock.cpp:148:5

  Thread T23 (tid=388553, running) created by main thread at:
    #0 pthread_create ...
    #1 main ./libc/test/integration/src/__support/threads/tsan_full_rwlock.cpp:166:5

  Thread T4 (tid=388533, running) created by main thread at:
    #0 pthread_create ...
    #1 main ./libc/test/integration/src/__support/threads/tsan_full_rwlock.cpp:166:5

SUMMARY: ThreadSanitizer: data race ./libc/src/__support/threads/raw_rwlock.h:443:44 in __llvm_libc_23_0_0_git::RawRwLock::notify_pending_threads()
==================
```

AI wrote the detection script. Manually fixed.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
I recently noticed LLDB crash during execution of `script
print(lldb.SBDebugger().GetBroadcaster().GetName())` command:
```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /home/sergei/llvm-project/build/bin/lldb-dap
 #0 0x000062735c3403d2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/sergei/llvm-project/build/bin/lldb-dap+0x7c3d2)
 #1 0x000062735c33d7ec llvm::sys::RunSignalHandlers() (/home/sergei/llvm-project/build/bin/lldb-dap+0x797ec)
 #2 0x000062735c33d94c SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007eaa6aa45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x00007eaa6bb0c092 lldb::SBBroadcaster::GetName() const (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x90c092)
 #5 0x00007eaa6bcb9a5d _wrap_SBBroadcaster_GetName LLDBWrapPython.cpp:0:0
 #6 0x00007eaa6a1df5f5 (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x1df5f5)
 #7 0x00007eaa6a182b2c PyObject_Vectorcall (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x182b2c)
 llvm#8 0x00007eaa6a11d5ee _PyEval_EvalFrameDefault (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x11d5ee)
 llvm#9 0x00007eaa6a2a091f PyEval_EvalCode (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x2a091f)
llvm#10 0x00007eaa6a29c8b0 (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x29c8b0)
llvm#11 0x00007eaa6a11fbd3 _PyEval_EvalFrameDefault (/lib/x86_64-linux-gnu/libpython3.12.so.1.0+0x11fbd3)
llvm#12 0x00007eaa6c4891b7 lldb_private::ScriptInterpreterPythonImpl::ExecuteOneLine(llvm::StringRef, lldb_private::CommandReturnObject*, lldb_private::ExecuteScriptOptions const&) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x12891b7)
llvm#13 0x00007eaa70326ff5 CommandObjectScriptingRun::DoExecute(llvm::StringRef, lldb_private::CommandReturnObject&) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x5126ff5)
llvm#14 0x00007eaa6bee3739 lldb_private::CommandObjectRaw::Execute(char const*, lldb_private::CommandReturnObject&) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0xce3739)
llvm#15 0x00007eaa6bede09a lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, bool) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0xcde09a)
llvm#16 0x00007eaa6bb0f0f8 lldb::SBCommandInterpreter::HandleCommand(char const*, lldb::SBExecutionContext&, lldb::SBCommandReturnObject&, bool) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x90f0f8)
llvm#17 0x00007eaa6bb0f265 lldb::SBCommandInterpreter::HandleCommand(char const*, lldb::SBCommandReturnObject&, bool) (/home/sergei/llvm-project/build/bin/../lib/liblldb.so.23.0git+0x90f265)
llvm#18 0x000062735c3707f3 lldb_dap::RunLLDBCommands[abi:cxx11](lldb::SBDebugger&, lldb::SBMutex, llvm::StringRef, llvm::ArrayRef<lldb_dap::protocol::String> const&, bool&, bool, bool) (/home/sergei/llvm-project/build/bin/lldb-dap+0xac7f3)
llvm#19 0x000062735c3a8019 lldb_dap::EvaluateRequestHandler::Run(lldb_dap::protocol::EvaluateArguments const&) const (/home/sergei/llvm-project/build/bin/lldb-dap+0xe4019)
llvm#20 0x000062735c3aba78 lldb_dap::RequestHandler<lldb_dap::protocol::EvaluateArguments, llvm::Expected<lldb_dap::protocol::EvaluateResponseBody>>::operator()(lldb_dap::protocol::Request const&) const (/home/sergei/llvm-project/build/bin/lldb-dap+0xe7a78)
llvm#21 0x000062735c3ce1bf lldb_dap::BaseRequestHandler::Run(lldb_dap::protocol::Request const&) (/home/sergei/llvm-project/build/bin/lldb-dap+0x10a1bf)
llvm#22 0x000062735c3577e7 lldb_dap::DAP::HandleObject(std::variant<lldb_dap::protocol::Request, lldb_dap::protocol::Response, lldb_dap::protocol::Event> const&) (/home/sergei/llvm-project/build/bin/lldb-dap+0x937e7)
llvm#23 0x000062735c358705 lldb_dap::DAP::Loop() (/home/sergei/llvm-project/build/bin/lldb-dap+0x94705)
llvm#24 0x000062735c2ed0c7 main (/home/sergei/llvm-project/build/bin/lldb-dap+0x290c7)
llvm#25 0x00007eaa6aa2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
```
As far as I understand default constuctors should be covered by fuzzing
tests, so I don't know how to write test for that patch.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…ructions (llvm#185170)

We currently emit `movi`+`ext` instructions when generating code for
shuffle slides of a 64-bit vector left/right and fill it with zeros.
This patch optimizes these patterns to use a single `ushr`/`shl`
instruction instead.

Example:
```llvm
  define <8 x i8> @slide_left(<8 x i8> %v) {
    %r = shufflevector <8 x i8> %v, <8 x i8> zeroinitializer,
         <8 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8>
    ret <8 x i8> %r
  }
```

Before, we generate:
```
  movi    v1.2d, #0
  ext     v0.8b, v0.8b, v1.8b, #1
```

Now:
```
  ushr    d0, d0, llvm#8
```

Fixes: llvm#183398
Alive2 proof: https://alive2.llvm.org/ce/z/QaW5CQ

---------

Signed-off-by: Dibri Nsofor <dibrinsofor@gmail.com>
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…m#204601)

When creating the new intrinsic declaration, use the correct pointer
argument (arg #1) from the existing call. Currently, we use arg #0
(size) and end up creating an invalid intrinsic declaration. However,
later on we do not use this declaration directly and instead call
`CreateLifetimeStart` or `CreateLifetimeEnd` IRBuilder functions that
end up creating valid intrinsic declarations. The net result is that we
are left with a stray unused invalid declaration.

Fix this issue by creating the intrinsic with the right pointer argument
type.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…lvm#191275)" (llvm#206816)

This reverts commit 0f51760.

A test fails with the commit
(llvm#191275 (comment)):

```
Traceback (most recent call last):
  File "/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 596, in test_python_source_frames
    self.assertNotIn("0xffffffffffffffff", output.lower())
AssertionError: '0xffffffffffffffff' unexpectedly found in "* thread #2, name = 'a.out', stop reason = breakpoint 1.1\n  * frame #0: compute_fibonacci at python_helper.py:7 [synthetic]\n    frame #1: process_data at python_helper.py:16 [synthetic]\n    frame #2: main at python_helper.py:27 [synthetic]\n    frame #3: 0x0000badc2de81358 a.out`thread_func(thread_num=0) at main.cpp:44:13\n    frame #4: 0x0000badc2de81f9c a.out`void std::__invoke_impl<void, void (*)(int), int>((null)=__invoke_other @ 0x0000f1555ebae74f, __f=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:61:14\n    frame #5: 0x0000badc2de81f18 a.out`std::__invoke_result<void (*)(int), int>::type std::__invoke<void (*)(int), int>(__fn=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:96:14\n    frame #6: 0x0000badc2de81ee4 a.out`void std::thread::_invoker<std::tuple<void (*)(int), int>>::_m_invoke<0ul, 1ul>(this=0x0000badc66845eb8, (null)=_index_tuple<0ul, 1ul> @ 0x0000f1555ebae7af) at std_thread.h:259:13\n    frame #7: 0x0000badc2de81e98 a.out`std::thread::_invoker<std::tuple<void (*)(int), int>>::operator()(this=0x0000badc66845eb8) at std_thread.h:266:11\n    frame llvm#8: 0x0000badc2de81d70 a.out`std::thread::_state_impl<std::thread::_invoker<std::tuple<void (*)(int), int>>>::_m_run(this=0xffffffffffffffff) at std_thread.h:211:13\n    frame llvm#9: 0x0000f1555ef029cc libstdc++.so.6`___lldb_unnamed_symbol_d29b0 + 28\n    frame llvm#10: 0x0000f1555ec30398 libc.so.6`___lldb_unnamed_symbol_800c0 + 728\n    frame llvm#11: 0x0000f1555ec99e9c libc.so.6`___lldb_unnamed_symbol_e9e90 + 12\n"
```

I don't know why this test fails with the PR, but I don't have time to
fix it now, so revert it to unblock CI.

The backtrace was
```
    frame #0: compute_fibonacci at python_helper.py:7 [synthetic]
    frame #1: process_data at python_helper.py:16 [synthetic]
    frame #2: main at python_helper.py:27 [synthetic]
    frame #3: 0x0000badc2de81358 a.out`thread_func(thread_num=0) at main.cpp:44:13
    frame #4: 0x0000badc2de81f9c a.out`void std::__invoke_impl<void, void (*)(int), int>((null)=__invoke_other @ 0x0000f1555ebae74f, __f=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:61:14
    frame #5: 0x0000badc2de81f18 a.out`std::__invoke_result<void (*)(int), int>::type std::__invoke<void (*)(int), int>(__fn=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:96:14
    frame #6: 0x0000badc2de81ee4 a.out`void std::thread::_invoker<std::tuple<void (*)(int), int>>::_m_invoke<0ul, 1ul>(this=0x0000badc66845eb8, (null)=_index_tuple<0ul, 1ul> @ 0x0000f1555ebae7af) at std_thread.h:259:13
    frame #7: 0x0000badc2de81e98 a.out`std::thread::_invoker<std::tuple<void (*)(int), int>>::operator()(this=0x0000badc66845eb8) at std_thread.h:266:11
    frame llvm#8: 0x0000badc2de81d70 a.out`std::thread::_state_impl<std::thread::_invoker<std::tuple<void (*)(int), int>>>::_m_run(this=0xffffffffffffffff) at std_thread.h:211:13
    frame llvm#9: 0x0000f1555ef029cc libstdc++.so.6`___lldb_unnamed_symbol_d29b0 + 28
    frame llvm#10: 0x0000f1555ec30398 libc.so.6`___lldb_unnamed_symbol_800c0 + 728
    frame llvm#11: 0x0000f1555ec99e9c libc.so.6`___lldb_unnamed_symbol_e9e90 + 12
```

This contains 0xffffffffffffffff in frame 8.
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
Summary

This builds on the accelerator plugin protocol
(llvm#201489) by letting a plugin
ask the client to create and connect a second
target — the mechanism a real backend (e.g. a GPU debug stub) uses to
surface
  the accelerator alongside the CPU process being debugged.

  ### What this adds

**Protocol** — a new `AcceleratorConnectionInfo` describing how the
client
  should bring up the accelerator target.

  **Client** — when an `AcceleratorActions` carries `connect_info`,
`ProcessGDBRemote` creates a new (empty) target, reverse-connects it to
the GDB
  server the plugin points.

  **Mock server (for testing)** — to exercise this end to end, the mock
accelerator plugin stands up an in-process GDB server backed by a
minimal fake
process: `ProcessMockAccelerator`, `ThreadMockAccelerator` and
`RegisterContextMockAccelerator`.

  ### Scope

Intentionally minimal: the goal is to create and show the second
(accelerator)
target. There is no register/memory modeling beyond what a connection
requires. Next set of PRs will build up on this.

  ### Testing


Demo of how this looks with this PR. (explicitly asking the native
process to stop at every breakpoint for testability)

```
satyajanga@devgpu011:toolchain $ ./bin/lldb
(lldb) file /home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out                                     Current executable set to '/home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out' (x86_64).
(lldb) log enable -f /tmp/packets.log gdb-remote packets                                                                                                                                 (lldb) r
Process 1430531 launched: '/home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out' (x86_64)
Process 1430531 stopped
(lldb) target list
Current targets:
* target #0: /home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1430531, state=stopped )
(lldb) c
Process 1430531 resuming
Process 1 stopped
* thread #1, name = 'Mock Accelerator Thread', stop reason = trace
       frame #0: 0x0000000000001004
error: memory read failed for 0x1000
Target 0: (a.out) stopped.
(lldb) target list
Current targets:
  target #0: /home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1430531, state=stopped )
* target #1: <none> ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1, state=stopped )
(lldb) c
Process 1 resuming
(lldb) target select 0
Current targets:
* target #0: /home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1430531, state=stopped )
  target #1: <none> ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1, state=running )
(lldb) c
Process 1430531 resuming
Process 1430531 stopped
(lldb) target list
Current targets:
* target #0: /home/satyajanga/llvm-sand/build/Debug/fbcode-x86_64/toolchain/lldb-test-build.noindex/accelerator/mock/TestMockAcceleratorActions/a.out ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1430531, state=stopped )
  target #1: <none> ( arch=x86_64-unknown-linux-gnu, platform=host, pid=1, state=running )
(lldb)
a.out │ internal accelerator-plugin (mock) breakpoint(-4).
```

Packet log, 
you can notice the actions set with breakpoint info and later responding
with connection info. and you can also see the 5 GPRs

```
lldb             < 104> send packet: $qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events+;vfork-events+;swbreak+;hwbreak+#cd
lldb             < 299> read packet: $PacketSize=131072;QStartNoAckMode+;qEcho+;native-signals+;QThreadSuffixSupported+;QListThreadsInStopReply+;qXfer:features:read+;QNonStop+;jMultiBreakpoint+;QPassSignals+;qXfer:auxv:read+;qXfer:libraries-svr4:read+;qXfer:siginfo:read+;accelerator-plugins+;multiprocess+;fork-events+;vfork-events+llvm#86
..
lldb             <  32> send packet: $jAcceleratorPluginInitialize#50
lldb             < 238> read packet: $[{"breakpoints":[{"by_address":null,"by_name":{"function_name":"mock_gpu_accelerator_initialize","shlib":null}],"identifier":1,"symbol_names":["mock_gpu_accelerator_compute"]}]],"identifier":1,"plugin_name":"mock","session_name":""}]]#2f
..
intern-state     < 314> send packet: $jAcceleratorPluginBreakpointHit:{"breakpoint":{"by_address":null,"by_name":{"function_name":"mock_gpu_accelerator_initialize","shlib":null}],"identifier":1,"symbol_names":["mock_gpu_accelerator_compute"]}],"plugin_name":"mock","symbol_values":[{"name":"mock_gpu_accelerator_compute","value":93824992235840}]]}]#e7
intern-state     < 487> read packet: ${"actions":{"breakpoints":[{"by_address":null,"by_name":{"function_name":"mock_gpu_accelerator_finish","shlib":"a.out"}],"identifier":3,"symbol_names":[]}],{"by_address":{"load_address":93824992235840}],"by_name":null,"identifier":2,"symbol_names":[]}],{"by_address":null,"by_name":{"function_name":"mock_gpu_accelerator_connect","shlib":null}],"identifier":4,"symbol_names":[]}]],"identifier":2,"plugin_name":"mock","session_name":""}],"auto_resume_native":false,"disable_bp":true}]#7d
..
..
intern-state     < 218> send packet: $jAcceleratorPluginBreakpointHit:{"breakpoint":{"by_address":null,"by_name":{"function_name":"mock_gpu_accelerator_connect","shlib":null}],"identifier":4,"symbol_names":[]}],"plugin_name":"mock","symbol_values":[]}]#d1
intern-state     < 268> read packet: ${"actions":{"breakpoints":[],"connect_info":{"connect_url":"connect://localhost:32893","exe_path":null,"synchronous":true,"triple":null}],"identifier":4,"plugin_name":"mock","session_name":"Mock Accelerator Session"}],"auto_resume_native":false,"disable_bp":true}]#8e
intern-state     <   1> send packet: +
intern-state     history[1] tid=0x15d41f <   1> send packet: +
intern-state     <  19> send packet: $QStartNoAckMode#b0
intern-state     <   1> read packet: +
intern-state     <   6> read packet: $OK#9a
intern-state     <   1> send packet: +
intern-state     < 104> send packet: $qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events+;vfork-events+;swbreak+;hwbreak+#cd
intern-state     < 159> read packet: $PacketSize=131072;QStartNoAckMode+;qEcho+;native-signals+;QThreadSuffixSupported+;QListThreadsInStopReply+;qXfer:features:read+;QNonStop+;jMultiBreakpoint+#f3
intern-state     <  26> send packet: $QThreadSuffixSupported#e4
intern-state     <   6> read packet: $OK#9a
intern-state     <  27> send packet: $QListThreadsInStopReply#21
intern-state     <   6> read packet: $OK#9a
intern-state     <  13> send packet: $qHostInfo#9b
intern-state     < 364> read packet: $triple:7838365f36342d2d6c696e75782d676e75;ptrsize:8;watchpoint_exceptions_received:after;endian:little;os_version:6.13.2;os_build:362e31332e322d305f66626b355f
68617264656e65645f7263325f305f67313733613962316463613431;os_kernel:233120534d5020576564204a756c2032332030393a32343a3330205044542032303235;hostname:6465766770753031312e656167322e66616365626f6f6b2e6
36f6d;#c4
intern-state     <  10> send packet: $vCont?llvm#49
intern-state     <  19> read packet: $vCont;c;C;s;S;t#11
intern-state     <  27> send packet: $qVAttachOrWaitSupported#38
intern-state     <   6> read packet: $OK#9a
intern-state     <  23> send packet: $QEnableErrorStrings#8c
intern-state     <   6> read packet: $OK#9a
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <   6> send packet: $qC#b4
intern-state     <   7> read packet: $QC1#c5
intern-state     <   5> send packet: $?#3f
intern-state     < 291> read packet: $T00thread:1;name:Mock Accelerator Thread;threads:1;thread-pcs:0000000000001004;00:0010000000000000;01:0110000000000000;02:0210000000000000;03:0310000000000000
;04:0410000000000000;05:0510000000000000;reason:trace;description:6d6f636b20616363656c657261746f72207468726561642073746f70706564;llvm#83
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <  43> send packet: $qXfer:features:read:target.xml:0,131071#78
intern-state     < 889> read packet: $l<?xml version="1.0"?>
<target version="1.0">
  <architecture>x86_64</architecture>
  <feature>
    <reg name="r0" bitsize="64" regnum="0" offset="0" encoding="uint" format="hex" group="General Purpose Registers" />
    <reg name="r1" bitsize="64" regnum="1" offset="8" encoding="uint" format="hex" group="General Purpose Registers" />
    <reg name="sp" bitsize="64" regnum="2" offset="16" encoding="uint" format="hex" group="General Purpose Registers" generic="sp" />
    <reg name="fp" bitsize="64" regnum="3" offset="24" encoding="uint" format="hex" group="General Purpose Registers" generic="fp" />
    <reg name="pc" bitsize="64" regnum="4" offset="32" encoding="uint" format="hex" group="General Purpose Registers" generic="pc" />
    <reg name="flags" bitsize="64" regnum="5" offset="40" encoding="uint" format="hex" group="General Purpose Registers" />
  </feature>
</target>
llvm#82
intern-state     <  19> send packet: $p0;thread:0001;llvm#89
intern-state     <  20> read packet: $0010000000000000#01
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <  19> send packet: $p0;thread:0001;llvm#89
intern-state     <  20> read packet: $0010000000000000#01
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <  16> send packet: $qProcessInfo#dc
intern-state     <   7> read packet: $E01#a6
intern-state     <  26> send packet: $qStructuredDataPlugins#02
intern-state     <   6> read packet: $[]#b8
intern-state     <  26> send packet: $qMemoryRegionInfo:1004#d9
intern-state     <  41> read packet: $error:6e6f7420696d706c656d656e746564;#f7
intern-state     <  16> send packet: $jThreadsInfo#c1
intern-state     < 198> read packet: $[{"description":"mock accelerator thread stopped","name":"Mock Accelerator Thread","reason":"trace","registers":{"2":"0210000000000000","3":"0310000000000000"
,"4":"0410000000000000"}],"tid":1}]]#4a

```
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
…long encodings (llvm#205907)

When a (signed or unsigned) LEB128 value is encoded with extra trailing
bytes that only carry zero- or sign-extension, the decode loop could
keep
running with the shift amount at 64 or beyond and then evaluate
`Slice << Shift`, which is undefined behavior for a 64-bit type.

The DWARF expression parser feeds attacker-controlled LEB128 operands
(such as `DW_OP_bregN` / `DW_OP_constu`) through
`DataExtractor::getULEB128` / `getSLEB128`, so the
`lldb-dwarf-expression-fuzzer` reaches this under UBSan.  The unsigned
case:

```
LEB128.h:152:20: runtime error: shift exponent 70 is too large for
64-bit type 'uint64_t' (aka 'unsigned long long')
    #0 llvm::decodeULEB128(...) LEB128.h:152
    #1 getLEB128<unsigned long long>(...) DataExtractor.cpp:227
    #2 llvm::DataExtractor::getULEB128(...) DataExtractor.cpp:241
    #3 llvm::DWARFExpression::Operation::extract(...) DWARFExpression.cpp:218
    #7 lldb_private::DWARFExpression::Evaluate(...) DWARFExpression.cpp:1333
    llvm#9 LLVMFuzzerTestOneInput lldb-dwarf-expression-fuzzer.cpp:83
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior LEB128.h:152:20
```

and the signed case, reached the same way:

```
LEB128.h:190:20: runtime error: shift exponent 70 is too large for
64-bit type 'uint64_t' (aka 'unsigned long long')
    #0 llvm::decodeSLEB128(...) LEB128.h:190
    #1 getLEB128<long long>(...) DataExtractor.cpp:227
    #2 llvm::DataExtractor::getSLEB128(...) DataExtractor.cpp:245
    #3 llvm::DWARFExpression::Operation::extract(...) DWARFExpression.cpp:216
    #7 lldb_private::DWARFExpression::Evaluate(...) DWARFExpression.cpp:1333
```

The existing range checks already guarantee that once `Shift` reaches 64
the remaining bytes are pure extension and contribute nothing to the
result, so skip the accumulating shift in that case.  Decoded values are
unchanged for all well-formed inputs.

Adds overlong-encoding regression cases to `LEB128Test`. Without the fix
the signed case is the UBSan diagnostic above in a sanitizer build, and
in a normal build the unsigned case also decodes to the wrong value (the
overlong `1` decodes as `11`).
sdkrystian pushed a commit that referenced this pull request Jul 20, 2026
The general rule is if si_addr is the same as the PC, we don't show it
because it doesn't add any new information.

SIGBUS signals are caused by an instruction trying to do something, but
si_addr is not the address of the instruction. It's some virtual
address, which is the important bit so add it to the description.

https://man7.org/linux/man-pages/man7/signal.7.html
> SIGBUS <...> Bus error (bad memory access)

Before:
```
* thread #1, name = 'test.o', stop reason = signal SIGBUS: illegal address
  * frame #0: 0x0000aaaaaaaa0b80 test.o`main at test.c:42:13
```
After:
```
* thread #1, name = 'test.o', stop reason = signal SIGBUS: illegal address (fault address=0xfffff7ff6000)
  * frame #0: 0x0000aaaaaaaa0b80 test.o`main at test.c:42:13
```
I am not adding test cases for this because:
* They would be architecture specific.
* Reliably generating BUS_OBJERR seems difficult.
* Signal reporting has good coverage as it is, so we know that
si_code/si_addr are handled correctly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants