[Bug 26875] New: LLDB GUI segfaults when selecting a particular stack frame

Bug ID 26875
Summary LLDB GUI segfaults when selecting a particular stack frame
Product lldb
Version 3.8
Hardware Macintosh
Status NEW
Severity normal
Priority P
Component All Bugs
Assignee lldb-dev@lists.llvm.org
Reporter kknb1056@gmail.com
CC llvm-bugs@lists.llvm.org
Classification Unclassified

Created attachment 16003 [details]
Source file of a program that causes a crash in LLDB

I've found I can consistently make the LLDB GUI crash with a particular series
of steps.  A simple source file is attached with instructions in the comments.

Basically, compile the file and start the program in LLDB; continue to a point
where all the threads have started (e.g. before the notify_all); open the gui
and select frame #11 of any of threads #2-#6. LLDB crashes.
This definitely happens on Mac OS X El Capitan with lldb-340.4.119.1 (which
ships with Xcode 7.2.1) as well as the LLDB head as at 08/Mar/16. All line
numbers here refer to the code as at 08/Mar/16.

This is unrelated to bug 26842 (https://llvm.org/bugs/show_bug.cgi?id=26842),
applying that patch has no effect.

The stack trace says the crash is in libncurses, however I'm fairly sure it's
because of memory corruption before hand. The corruption comes when querying
the frame variables to populate the "Variables" window, and it's one variable
in particular - the first one "void * _vp" in frame 11 which is the function

** To show it's when populating the Variables window: **
Before the crash, attach another debugger to the original lldb with the
following breakpoint (should be on the "if (value_sp)" line):

    breakpoint set -f IOHandler.cpp -l 3922 -N skipVarAdd
    breakpoint command add skipVarAdd
    expression value_sp=nullptr

This stops any variables being added to the window and there is no crash. You
can also optionally add "--condition i==0" and only enable it before going from
frame 10 to frame 11 to show that it's the first variable in frame 11.

** To show it's a memory corruption unrelated to ncurses **
Again, in a second debugger attached to the first (line 3933 should be "

    breakpoint set -f IOHandler.cpp -l 3933 -N clearVars
    breakpoint command add clearVars
    expression class ValueObjectList $emptyList
    expression local_values=$emptyList

This empties the local list *before* being added to anything that is persisted
beyond the current function. The crash still happens.

It's possible to investigate this further, but I modified the code because I
couldn't figure out how to do it with breakpoints. Just having line 3924
"value_sp->GetSyntheticValue();" is enough to cause the crash (comment out the
"local_value.Append" lines); but also skipping that and adding just value_sp
causes a crash (comment out everything except line 3928
"local_values.Append(value_sp);"). So just using value_sp in any way seems to
be an issue.

** To show it's a problem with the dynamic value **
Again in a second debugger (line should be "if (dynamic_sp)"):

    breakpoint set -f StackFrame.cpp -l 1308 -N refuseDynamic
    breakpoint command add refuseDynamic
    expression dynamic_sp=nullptr

This makes the gui never use the dynamic value, and everything runs fine.

** To show it's probably(?) a GUI initialisation problem **
Selecting one of the problem frames in any of the threads *before* starting the
gui allows the program to run fine. The frame doesn't even need to be active
when the gui starts, just selected at some point before hand.  E.g. in original
debugger attached to executable

    breakpoint set --file main.cpp --line 64
    process launch
    thread select 2
    frame select 11
    thread select 1

Then navigate to frame 11 as before and there are no problems. Even navigating
to frame 11 of the other threads (3-6) is fine.

I've tried stepping through the gui initialisation with and without a manual
"frame select 11" and I can't find any notable differences.  I've also tried
stepping through the manual "frame select 11" to see what it does differently
and can't find anything there either.