History

Change assert to exception if a dis module contains an invalid magic number. Broken threads now terminate the VM using the default scheduler. Tools can not get a callback for broken threads.

arr committed 10 years ago

Commit 096b0c71 parent 9c1abd69 files · +74 −28Browse files

Showing the changes to src/vm/thread.cpp (1 of 9 files). Show all

Unified · Split

src/vm/thread.cpp+33−16
@@ -111,6 +111,7 @@ vm_thread_t::vm_thread_t( · 110 unmodified lines
111111 vm_module_ref_t &entry,
112112 uint32_t parent_thread_id)
113113 : vm_alloc_t(vm_thread_t::type_desc())
114+ , _error_message{ nullptr }
114115 , _parent_thread_id{ parent_thread_id }
115116 , _registers{ *this, entry }
116117 , _thread_id{ get_unique_thread_id() }
@@ -135,6 +136,7 @@ vm_thread_t::vm_thread_t( · 18 unmodified lines
135136 const vm_frame_t &initial_frame,
136137 vm_pc_t start_pc)
137138 : vm_alloc_t(vm_thread_t::type_desc())
139+ , _error_message{ nullptr }
138140 , _parent_thread_id{ parent_thread_id }
139141 , _registers{ *this, entry }
140142 , _thread_id{ get_unique_thread_id() }
@@ -162,6 +164,9 @@ vm_thread_t::~vm_thread_t() · 21 unmodified lines
162164 {
163165 if (debug::is_component_tracing_enabled<debug::component_trace_t::thread>())
164166 debug::log_msg(debug::component_trace_t::thread, debug::log_level_t::debug, "destroy: vm thread: %d %d\n", _thread_id, _parent_thread_id);
167+
168+ free_memory(_error_message);
169+ debug::assign_debug_pointer(&_error_message);
165170 }
166171
167172 namespace
@@ -214,6 +219,7 @@ namespace · 46 unmodified lines
214219
215220 vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta)
216221 {
222+ const auto max_error_message = std::size_t{ 1024 };
217223 _registers.current_thread_state = vm_thread_state_t::running;
218224 _registers.current_thread_quanta = quanta;
219225 assert(_registers.pc != runtime_constants::invalid_program_counter);
@@ -226,27 +232,27 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 6 unmodified lines
226232 else
227233 execute_impl<execute_with_tool_t>(_registers, vm);
228234 }
235+ catch (const vm_term_request &)
236+ {
237+ throw;
238+ }
229239 catch (const unhandled_user_exception &uue)
230240 {
231− // [TODO] Store the exception
232− std::fprintf(stderr, "%s - '%s' in %s at instruction %d\n", uue.what(), uue.exception_id, uue.module_name, uue.program_counter);
241+ _error_message = calloc_memory<char>(max_error_message);
242+ std::snprintf(_error_message, max_error_message, "%s - '%s' in %s at instruction %d", uue.what(), uue.exception_id, uue.module_name, uue.program_counter);
233243 _registers.current_thread_state = vm_thread_state_t::broken;
234− if (tool_dispatch != nullptr)
235− tool_dispatch->on_thread_broken(*this);
236244 }
237245 catch (const index_out_of_range_memory &ioor)
238246 {
239− std::fprintf(stderr, "%s - %d [%d,%d]\n", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max);
247+ _error_message = calloc_memory<char>(max_error_message);
248+ std::snprintf(_error_message, max_error_message, "%s - %d [%d,%d]", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max);
240249 _registers.current_thread_state = vm_thread_state_t::broken;
241− if (tool_dispatch != nullptr)
242− tool_dispatch->on_thread_broken(*this);
243250 }
244251 catch (const vm_user_exception &ue)
245252 {
246− std::fprintf(stderr, "%s\n", ue.what());
253+ _error_message = calloc_memory<char>(max_error_message);
254+ std::snprintf(_error_message, max_error_message, "%s", ue.what());
247255 _registers.current_thread_state = vm_thread_state_t::broken;
248− if (tool_dispatch != nullptr)
249− tool_dispatch->on_thread_broken(*this);
250256 }
251257
252258 // Log the execution result
@@ -262,16 +268,22 @@ vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta) · 9 unmodified lines
262268 _registers.current_thread_state);
263269 }
264270
265− // If the thread is still in the running state transition it back to its entry state.
266− if (_registers.current_thread_state == vm_thread_state_t::running)
271+ switch (_registers.current_thread_state)
267272 {
273+ case vm_thread_state_t::running:
268274 _registers.current_thread_state = (tool_dispatch == nullptr) ? vm_thread_state_t::ready : vm_thread_state_t::debug;
269− }
270− else if (vm_thread_state_t::exiting == _registers.current_thread_state
271− || vm_thread_state_t::empty_stack == _registers.current_thread_state)
272− {
275+ break;
276+
277+ case vm_thread_state_t::empty_stack:
278+ case vm_thread_state_t::exiting:
273279 if (tool_dispatch != nullptr)
274280 tool_dispatch->on_thread_end(*this);
281+ break;
282+
283+ case vm_thread_state_t::broken:
284+ if (tool_dispatch != nullptr)
285+ tool_dispatch->on_thread_broken(*this);
286+ break;
275287 }
276288
277289 return _registers.current_thread_state;
@@ -288,6 +300,11 @@ vm_thread_state_t vm_thread_t::get_state() const · 10 unmodified lines
288300 return _registers.current_thread_state;
289301 }
290302
303+const char *vm_thread_t::get_error_message() const
304+{
305+ return _error_message;
306+}
307+
291308 uint32_t vm_thread_t::get_thread_id() const
292309 {
293310 return _thread_id;