History

Add debugger option (vm-dbg) for help during VM bug investigations

arr committed 9 years ago

Commit 220aaf21 parent b92328e1 file · +63 −18Browse files

Showing the changes to src/exec/debugger.cpp (1 of 1 file). Show all

Unified · Split

src/exec/debugger.cpp+63−18
@@ -53,6 +53,14 @@ namespace · 52 unmodified lines
53#undef CSI53#undef CSI
54 }54 }
55 55
56 bool vm_debug_enabled = false;
57
58 template<typename T>
59 struct vm_dbg_type final
60 {
61 T t;
62 };
63
56 struct debug_cmd_error_t : std::runtime_error64 struct debug_cmd_error_t : std::runtime_error
57 {65 {
58 debug_cmd_error_t(const char *message)66 debug_cmd_error_t(const char *message)
@@ -183,6 +191,17 @@ namespace · 124 unmodified lines
183 return register_string.str();191 return register_string.str();
184 }192 }
185 193
194 std::ostream& operator<<(std::ostream &ss, const std::shared_ptr<const type_descriptor_t> &t)
195 {
196 ss << "size: " << t->size_in_bytes;
197
198#ifndef NDEBUG
199 ss << " n: " << t->debug_type_name;
200#endif
201
202 return ss;
203 }
204
186 std::ostream& operator<<(std::ostream &ss, const vm_string_t *s)205 std::ostream& operator<<(std::ostream &ss, const vm_string_t *s)
187 {206 {
188 auto escaped_string = std::stringstream{};207 auto escaped_string = std::stringstream{};
@@ -225,57 +244,72 @@ namespace · 36 unmodified lines
225 }244 }
226 }245 }
227 246
228 ss << escaped_string.str() << " length: " << s->get_length() << " string";247 ss << escaped_string.str() << " length: " << s->get_length() << " - string";
229 248
230 return ss;249 return ss;
231 }250 }
232 251
233 std::ostream& operator<<(std::ostream &ss, const vm_array_t *a)252 std::ostream& operator<<(std::ostream &ss, const vm_array_t *a)
234 {253 {
235 ss << "length: " << a->get_length() << " array";254 ss << "length: " << a->get_length()
255 << " - array of " << a->get_element_type();
236 256
237 return ss;257 return ss;
238 }258 }
239 259
240 std::ostream& operator<<(std::ostream &ss, const vm_list_t *l)260 std::ostream& operator<<(std::ostream &ss, const vm_list_t *l)
241 {261 {
242 ss << "length: " << l->get_length() << " list";262 ss << "length: " << l->get_length()
263 << " - list of " << l->get_element_type();
243 264
244 return ss;265 return ss;
245 }266 }
246 267
247 std::ostream& operator<<(std::ostream &ss, const vm_channel_t *c)268 std::ostream& operator<<(std::ostream &ss, const vm_channel_t *c)
248 {269 {
249 ss << "buffer size: " << c->get_buffer_size() << " channel";270 ss << "buffer size: " << c->get_buffer_size()
271 << " - channel of" << c->get_data_type();
250 272
251 return ss;273 return ss;
252 }274 }
253 275
276 std::ostream& operator<<(std::ostream &ss, const vm_dbg_type<const vm_alloc_t *> &dbg_alloc)
277 {
278 if (!vm_debug_enabled)
279 return ss;
280
281 return ss
282 << " [[ref: " << dbg_alloc.t->get_ref_count()
283 << " addr: " << reinterpret_cast<const void *>(dbg_alloc.t)
284 << " gc_res: " << reinterpret_cast<const void *>(dbg_alloc.t->gc_reserved)
285 << "]]";
286 }
287
254 std::ostream& safe_alloc_print(std::ostream &ss, const vm_alloc_t *alloc, int recurse_depth)288 std::ostream& safe_alloc_print(std::ostream &ss, const vm_alloc_t *alloc, int recurse_depth)
255 {289 {
256 if (alloc == nullptr)290 if (alloc == nullptr)
291 return ss << "<nil>";
292
293 vm_dbg_type<const vm_alloc_t *> dbg_alloc{ alloc };
294 if (alloc->alloc_type == intrinsic_type_desc::type<vm_string_t>())
257 {295 {
258 ss << "<nil>";296 ss << vm_alloc_t::from_allocation<vm_string_t>(alloc->get_allocation()) << dbg_alloc;
259 }
260 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_string_t>())
261 {
262 ss << vm_alloc_t::from_allocation<vm_string_t>(alloc->get_allocation());
263 }297 }
264 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_array_t>())298 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_array_t>())
265 {299 {
266 ss << vm_alloc_t::from_allocation<vm_array_t>(alloc->get_allocation());300 ss << vm_alloc_t::from_allocation<vm_array_t>(alloc->get_allocation()) << dbg_alloc;
267 }301 }
268 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_list_t>())302 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_list_t>())
269 {303 {
270 ss << vm_alloc_t::from_allocation<vm_list_t>(alloc->get_allocation());304 ss << vm_alloc_t::from_allocation<vm_list_t>(alloc->get_allocation()) << dbg_alloc;
271 }305 }
272 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_channel_t>())306 else if (alloc->alloc_type == intrinsic_type_desc::type<vm_channel_t>())
273 {307 {
274 ss << vm_alloc_t::from_allocation<vm_channel_t>(alloc->get_allocation());308 ss << vm_alloc_t::from_allocation<vm_channel_t>(alloc->get_allocation()) << dbg_alloc;
275 }309 }
276 else310 else
277 {311 {
278 ss << "size: " << alloc->alloc_type->size_in_bytes << " alloc";312 ss << alloc->alloc_type << " - alloc" << dbg_alloc;
279 313
280 enum_pointer_fields(*alloc->alloc_type, alloc->get_allocation(), [&ss, recurse_depth](pointer_t p, std::size_t o)314 enum_pointer_fields(*alloc->alloc_type, alloc->get_allocation(), [&ss, recurse_depth](pointer_t p, std::size_t o)
281 {315 {
@@ -867,7 +901,8 @@ namespace · 585 unmodified lines
867 std::set<std::string> dbg_options =901 std::set<std::string> dbg_options =
868 {902 {
869 { "bp-cmd" },903 { "bp-cmd" },
870 { "step-cmd" }904 { "step-cmd" },
905 { "vm-dbg" }
871 };906 };
872 907
873 void set_value_cmd(const std::vector<std::string> &args, dbg_cmd_cxt_t &cxt)908 void set_value_cmd(const std::vector<std::string> &args, dbg_cmd_cxt_t &cxt)
@@ -893,19 +928,29 @@ namespace · 19 unmodified lines
893 if (std::cend(dbg_options) == dbg_options.find(curr_option))928 if (std::cend(dbg_options) == dbg_options.find(curr_option))
894 throw debug_cmd_error_t{ "Invalid debug option" };929 throw debug_cmd_error_t{ "Invalid debug option" };
895 930
896 auto new_value = std::stringstream{};931 auto ss_value = std::stringstream{};
897 932
898 // Reconstitute the parsed debug arguments - in-case of space breaks.933 // Reconstitute the parsed debug arguments - in-case of space breaks.
899 for (auto i = std::size_t{ 2 }; i < args.size(); ++i)934 for (auto i = std::size_t{ 2 }; i < args.size(); ++i)
900 {935 {
901 new_value << args[i];936 ss_value << args[i];
902 937
903 // For the last parsed arg938 // For the last parsed arg
904 if (i + 1 < args.size())939 if (i + 1 < args.size())
905 new_value << " ";940 ss_value << " ";
941 }
942
943 auto new_value = ss_value.str();
944 if (std::strcmp(curr_option.c_str(), "vm-dbg") == 0)
945 {
946 vm_debug_enabled = !new_value.empty();
947 if (vm_debug_enabled)
948 new_value = "true";
949 else
950 new_value = "";
906 }951 }
907 952
908 cxt.dbg.set_option(curr_option, new_value.str());953 cxt.dbg.set_option(curr_option, new_value);
909 }954 }
910 955
911 const dbg_cmd_t cmds[] =956 const dbg_cmd_t cmds[] =