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
111 vm_module_ref_t &entry,111 vm_module_ref_t &entry,
112 uint32_t parent_thread_id)112 uint32_t parent_thread_id)
113 : vm_alloc_t(vm_thread_t::type_desc())113 : vm_alloc_t(vm_thread_t::type_desc())
114 , _error_message{ nullptr }
114 , _parent_thread_id{ parent_thread_id }115 , _parent_thread_id{ parent_thread_id }
115 , _registers{ *this, entry }116 , _registers{ *this, entry }
116 , _thread_id{ get_unique_thread_id() }117 , _thread_id{ get_unique_thread_id() }
@@ -135,6 +136,7 @@ vm_thread_t::vm_thread_t( · 18 unmodified lines
135 const vm_frame_t &initial_frame,136 const vm_frame_t &initial_frame,
136 vm_pc_t start_pc)137 vm_pc_t start_pc)
137 : vm_alloc_t(vm_thread_t::type_desc())138 : vm_alloc_t(vm_thread_t::type_desc())
139 , _error_message{ nullptr }
138 , _parent_thread_id{ parent_thread_id }140 , _parent_thread_id{ parent_thread_id }
139 , _registers{ *this, entry }141 , _registers{ *this, entry }
140 , _thread_id{ get_unique_thread_id() }142 , _thread_id{ get_unique_thread_id() }
@@ -162,6 +164,9 @@ vm_thread_t::~vm_thread_t() · 21 unmodified lines
162{164{
163 if (debug::is_component_tracing_enabled<debug::component_trace_t::thread>())165 if (debug::is_component_tracing_enabled<debug::component_trace_t::thread>())
164 debug::log_msg(debug::component_trace_t::thread, debug::log_level_t::debug, "destroy: vm thread: %d %d\n", _thread_id, _parent_thread_id);166 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);
165}170}
166 171
167namespace172namespace
@@ -214,6 +219,7 @@ namespace · 46 unmodified lines
214 219
215vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta)220vm_thread_state_t vm_thread_t::execute(vm_t &vm, const uint32_t quanta)
216{221{
222 const auto max_error_message = std::size_t{ 1024 };
217 _registers.current_thread_state = vm_thread_state_t::running;223 _registers.current_thread_state = vm_thread_state_t::running;
218 _registers.current_thread_quanta = quanta;224 _registers.current_thread_quanta = quanta;
219 assert(_registers.pc != runtime_constants::invalid_program_counter);225 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
226 else232 else
227 execute_impl<execute_with_tool_t>(_registers, vm);233 execute_impl<execute_with_tool_t>(_registers, vm);
228 }234 }
235 catch (const vm_term_request &)
236 {
237 throw;
238 }
229 catch (const unhandled_user_exception &uue)239 catch (const unhandled_user_exception &uue)
230 {240 {
231 // [TODO] Store the exception241 _error_message = calloc_memory<char>(max_error_message);
232 std::fprintf(stderr, "%s - '%s' in %s at instruction %d\n", uue.what(), uue.exception_id, uue.module_name, uue.program_counter);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);
233 _registers.current_thread_state = vm_thread_state_t::broken;243 _registers.current_thread_state = vm_thread_state_t::broken;
234 if (tool_dispatch != nullptr)
235 tool_dispatch->on_thread_broken(*this);
236 }244 }
237 catch (const index_out_of_range_memory &ioor)245 catch (const index_out_of_range_memory &ioor)
238 {246 {
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);
240 _registers.current_thread_state = vm_thread_state_t::broken;249 _registers.current_thread_state = vm_thread_state_t::broken;
241 if (tool_dispatch != nullptr)
242 tool_dispatch->on_thread_broken(*this);
243 }250 }
244 catch (const vm_user_exception &ue)251 catch (const vm_user_exception &ue)
245 {252 {
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());
247 _registers.current_thread_state = vm_thread_state_t::broken;255 _registers.current_thread_state = vm_thread_state_t::broken;
248 if (tool_dispatch != nullptr)
249 tool_dispatch->on_thread_broken(*this);
250 }256 }
251 257
252 // Log the execution result258 // 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
262 _registers.current_thread_state);268 _registers.current_thread_state);
263 }269 }
264 270
265 // If the thread is still in the running state transition it back to its entry state.271 switch (_registers.current_thread_state)
266 if (_registers.current_thread_state == vm_thread_state_t::running)
267 {272 {
273 case vm_thread_state_t::running:
268 _registers.current_thread_state = (tool_dispatch == nullptr) ? vm_thread_state_t::ready : vm_thread_state_t::debug;274 _registers.current_thread_state = (tool_dispatch == nullptr) ? vm_thread_state_t::ready : vm_thread_state_t::debug;
269 }275 break;
270 else if (vm_thread_state_t::exiting == _registers.current_thread_state276
271 || vm_thread_state_t::empty_stack == _registers.current_thread_state)277 case vm_thread_state_t::empty_stack:
272 {278 case vm_thread_state_t::exiting:
273 if (tool_dispatch != nullptr)279 if (tool_dispatch != nullptr)
274 tool_dispatch->on_thread_end(*this);280 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;
275 }287 }
276 288
277 return _registers.current_thread_state;289 return _registers.current_thread_state;
@@ -288,6 +300,11 @@ vm_thread_state_t vm_thread_t::get_state() const · 10 unmodified lines
288 return _registers.current_thread_state;300 return _registers.current_thread_state;
289}301}
290 302
303const char *vm_thread_t::get_error_message() const
304{
305 return _error_message;
306}
307
291uint32_t vm_thread_t::get_thread_id() const308uint32_t vm_thread_t::get_thread_id() const
292{309{
293 return _thread_id;310 return _thread_id;