-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lldb][gui] Update TreeItem children's m_parent on move
Before this patch, any time TreeItem is copied in Resize method, its parent is not updated, which can cause crashes when, for example, thread window with multiple hierarchy levels is updated. Makes TreeItem move-only, removes TreeItem's m_delegate extra self-assignment by making it a pointer, adds code to fix up children's parent on move constructor and operator= Patch prepared by NH5pml30 ~~~ Huawei RRI, OS Lab Reviewed By: clayborg Differential Revision: https://reviews.llvm.org/D157960
- Loading branch information
Showing
4 changed files
with
135 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CXX_SOURCES := main.cpp | ||
ENABLE_THREADS := YES | ||
include Makefile.rules |
47 changes: 47 additions & 0 deletions
47
lldb/test/API/commands/gui/spawn-threads/TestGuiSpawnThreads.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
""" | ||
Test that 'gui' does not crash when adding new threads, which | ||
populate TreeItem's children and may be reallocated elsewhere. | ||
""" | ||
|
||
import lldb | ||
from lldbsuite.test.decorators import * | ||
from lldbsuite.test.lldbtest import * | ||
from lldbsuite.test.lldbpexpect import PExpectTest | ||
|
||
import sys | ||
|
||
class TestGuiSpawnThreadsTest(PExpectTest): | ||
# PExpect uses many timeouts internally and doesn't play well | ||
# under ASAN on a loaded machine.. | ||
@skipIfAsan | ||
@skipIfCursesSupportMissing | ||
def test_gui(self): | ||
self.build() | ||
|
||
self.launch(executable=self.getBuildArtifact('a.out'), dimensions=(100, 500)) | ||
self.expect( | ||
'breakpoint set -f main.cpp -p "break here"', substrs=['Breakpoint 1', 'address ='] | ||
) | ||
self.expect( | ||
'breakpoint set -f main.cpp -p "before join"', substrs=['Breakpoint 2', 'address ='] | ||
) | ||
self.expect("run", substrs=["stop reason ="]) | ||
|
||
escape_key = chr(27).encode() | ||
|
||
# Start the GUI | ||
self.child.sendline("gui") | ||
self.child.expect_exact("Threads") | ||
self.child.expect_exact(f"thread #1: tid =") | ||
|
||
for i in range(5): | ||
# Stopped at the breakpoint, continue over the thread creation | ||
self.child.send("c") | ||
# Check the newly created thread | ||
self.child.expect_exact(f"thread #{i + 2}: tid =") | ||
|
||
# Exit GUI. | ||
self.child.send(escape_key) | ||
self.expect_prompt() | ||
|
||
self.quit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <iostream> | ||
#include <thread> | ||
#include <vector> | ||
|
||
#include "pseudo_barrier.h" | ||
|
||
pseudo_barrier_t barrier_inside; | ||
|
||
void thread_func() { pseudo_barrier_wait(barrier_inside); } | ||
|
||
void test_thread() { | ||
std::vector<std::thread> thrs; | ||
for (int i = 0; i < 5; i++) | ||
thrs.push_back(std::thread(thread_func)); // break here | ||
|
||
pseudo_barrier_wait(barrier_inside); // break before join | ||
for (auto &t : thrs) | ||
t.join(); | ||
} | ||
|
||
int main() { | ||
pseudo_barrier_init(barrier_inside, 6); | ||
test_thread(); | ||
return 0; | ||
} |