Ticket #9437: how-to-reproduce.cpp

File how-to-reproduce.cpp, 2.2 KB (added by Evgeny Shapovalov <johncapfull@…>, 9 years ago)

Full source code to reproduce described issues

Line 
1#include <cstdlib>
2#include <iostream>
3
4#include <boost/context/all.hpp>
5
6namespace {
7 template< std::size_t Max, std::size_t Default, std::size_t Min >
8 class simple_stack_allocator
9 {
10 public:
11 static std::size_t maximum_stacksize()
12 { return Max; }
13
14 static std::size_t default_stacksize()
15 { return Default; }
16
17 static std::size_t minimum_stacksize()
18 { return Min; }
19
20 void * allocate( std::size_t size) const
21 {
22 BOOST_ASSERT( minimum_stacksize() <= size);
23 BOOST_ASSERT( maximum_stacksize() >= size);
24
25 void * limit = std::calloc( size, sizeof( char) );
26 if ( ! limit) throw std::bad_alloc();
27
28 return static_cast< char * >( limit) + size;
29 }
30
31 void deallocate( void * vp, std::size_t size) const
32 {
33 BOOST_ASSERT( vp);
34 BOOST_ASSERT( minimum_stacksize() <= size);
35 BOOST_ASSERT( maximum_stacksize() >= size);
36
37 void * limit = static_cast< char * >( vp) - size;
38 std::free( limit);
39 }
40 };
41}
42
43namespace sample {
44 namespace ctx = yboost::context;
45
46 typedef simple_stack_allocator<
47 8 * 1024 * 1024, // 8MB
48 64 * 1024, // 64kB
49 8 * 1024 // 8kB
50 > stack_allocator;
51
52 ctx::fcontext_t fcm;
53 ctx::fcontext_t* fc = 0;
54
55 void do_throw() {
56 throw std::exception();
57 }
58
59 void routine(intptr_t) {
60 try {
61 ctx::jump_fcontext(fc, &fcm, 0);
62 do_throw();
63 } catch(std::exception) {
64 std::cout << "exception caught" << std::endl;
65 }
66 ctx::jump_fcontext(fc, &fcm, 0);
67 }
68
69 void try_jump() {
70 try {
71 ctx::jump_fcontext(&fcm, fc, 0);
72 } catch (...) {
73 }
74 }
75
76 void test() {
77 stack_allocator alloc;
78 void* base = alloc.allocate(stack_allocator::default_stacksize());
79 fc = ctx::make_fcontext(base, stack_allocator::default_stacksize(), routine);
80
81 try_jump();
82 ctx::jump_fcontext(&fcm, fc, 0);
83 }
84}
85
86
87int main(int argc, const char * argv[]) {
88 sample::test();
89}