diff --git a/tests/stack_trace.test.vim b/tests/stack_trace.test.vim new file mode 100644 index 0000000..675f061 --- /dev/null +++ b/tests/stack_trace.test.vim @@ -0,0 +1,49 @@ +let s:fn='testdata/cpp/simple/threads.cpp' + +function! SetUp() + call vimspector#test#setup#SetUpWithMappings( 'HUMAN' ) +endfunction + +function! ClearDown() + call vimspector#test#setup#ClearDown() +endfunction + +function! s:StartDebugging() + exe 'edit ' . s:fn + call vimspector#SetLineBreakpoint( s:fn, 13 ) + call vimspector#Launch() + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 13, 1 ) +endfunction + +function! Test_Multiple_Threads() + call vimspector#SetLineBreakpoint( s:fn, 41 ) + call vimspector#SetLineBreakpoint( s:fn, 51 ) + call s:StartDebugging() + + call vimspector#Continue() + + " As we step through the thread creation we should get Thread events + + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 ) + call vimspector#Continue() + + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 ) + call vimspector#Continue() + + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 ) + call vimspector#Continue() + + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 ) + call vimspector#Continue() + + " This is the last one + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 ) + call vimspector#Continue() + + " So we break out of the loop + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 51, 1 ) + + call vimspector#ClearBreakpoints() + call vimspector#test#setup#Reset() + %bwipe! +endfunction diff --git a/tests/testdata/cpp/simple/.gitignore b/tests/testdata/cpp/simple/.gitignore index d3a7590..d64075c 100644 --- a/tests/testdata/cpp/simple/.gitignore +++ b/tests/testdata/cpp/simple/.gitignore @@ -2,3 +2,4 @@ simple variables struct printer +threads diff --git a/tests/testdata/cpp/simple/.ycm_extra_conf.py b/tests/testdata/cpp/simple/.ycm_extra_conf.py index 78a71f0..c9117c6 100644 --- a/tests/testdata/cpp/simple/.ycm_extra_conf.py +++ b/tests/testdata/cpp/simple/.ycm_extra_conf.py @@ -2,6 +2,7 @@ def Settings( **kwargs ): return { 'flags': [ '-x', 'c++', + '-std=c++17', '-Wextra', '-Werror', '-Wall' ] } diff --git a/tests/testdata/cpp/simple/Makefile b/tests/testdata/cpp/simple/Makefile index 85690c5..d3487aa 100644 --- a/tests/testdata/cpp/simple/Makefile +++ b/tests/testdata/cpp/simple/Makefile @@ -2,7 +2,7 @@ CXXFLAGS=-g -O0 -std=c++17 .PHONY: all -TARGETS=simple variables struct printer +TARGETS=simple variables struct printer threads all: $(TARGETS) diff --git a/tests/testdata/cpp/simple/threads.cpp b/tests/testdata/cpp/simple/threads.cpp new file mode 100644 index 0000000..45f8f42 --- /dev/null +++ b/tests/testdata/cpp/simple/threads.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main( int argc, char ** argv ) +{ + int numThreads = {}; + if ( argc < 2 ) + { + numThreads = 5; + } + else + { + std::string_view numThreadArg( argv[ 1 ] ); + if ( auto [ p, ec ] = std::from_chars( numThreadArg.begin(), + numThreadArg.end(), + numThreads ); + ec != std::errc() ) + { + std::cerr << "Usage " << argv[ 0 ] << " \n"; + return 2; + } + } + + std::cout << "Creating " << numThreads << " threads" << '\n'; + + std::vector threads{}; + threads.reserve( numThreads ); + + auto eng = std::default_random_engine() ; + auto dist = std::uniform_int_distribution( 250, 1000 ); + + for ( int i = 0; i < numThreads; ++i ) + { + using namespace std::chrono_literals; + threads.emplace_back( [&,tnum=i]() { + std::cout << "Started thread " << tnum << '\n'; + std::this_thread::sleep_for( + 5s + std::chrono::milliseconds( dist( eng ) ) ); + std::cout << "Completed thread " << tnum << '\n'; + }); + } + + + for ( int i = 0; i < numThreads; ++i ) + { + threads[ i ].join(); + } + + return 0; +}