3 #include "jdb_module.h"
6 #include "string_buffer.h"
11 class Jdb_kobject_handler;
13 class Jdb_kobject : public Jdb_module
16 typedef cxx::S_list_tail<Jdb_kobject_handler> Handler_list;
17 typedef Handler_list::Const_iterator Handler_iter;
21 Handler_list handlers;
22 Handler_list global_handlers;
29 class Jdb_kobject_handler : public cxx::S_list_item
31 friend class Jdb_kobject;
35 Jdb_kobject_handler(T const *) : kobj_type(cxx::Typeid<T>::get()) {}
36 Jdb_kobject_handler() : kobj_type(0) {}
37 cxx::Type_info const *kobj_type;
38 virtual bool show_kobject(Kobject_common *o, int level) = 0;
39 virtual void show_kobject_short(String_buffer *, Kobject_common *) {}
40 virtual Kobject_common *follow_link(Kobject_common *o) { return o; }
41 virtual ~Jdb_kobject_handler() {}
42 virtual bool invoke(Kobject_common *o, Syscall_frame *f, Utcb *utcb);
43 virtual bool handle_key(Kobject_common *, int /*keycode*/) { return false; }
44 virtual Kobject *parent(Kobject_common *) { return 0; }
45 virtual char const *kobject_type(Kobject_common *o) const
46 { return _kobject_type(o); }
48 static char const *_kobject_type(Kobject_common *o)
50 char const *n = cxx::dyn_typeid(o)->name;
51 static char const prefix[] =
52 "const char* cxx::_dyn::name_of() [with T = ";
54 if (strncmp(n, prefix, sizeof(prefix)-1) == 0)
55 return n + sizeof(prefix) - 1;
59 bool is_global() const { return !kobj_type; }
66 Op_query_log_typeid = 3,
69 Op_query_log_name = 6,
73 class Jdb_kobject_extension : public Kobject_dbg::Dbg_extension
76 virtual ~Jdb_kobject_extension() {}
77 virtual char const *type() const = 0;
80 class Jdb_kobject_list : public Jdb_list
83 typedef bool Filter_func(Kobject_common const *);
85 struct Mode : cxx::S_list_item
89 typedef cxx::S_list_bss<Mode> Mode_list;
90 static Mode_list modes;
92 Mode(char const *name, Filter_func *filter)
93 : name(name), filter(filter)
95 // make sure that non-filtered mode is first in the list so that we
96 // get this one displayed initially
98 modes.push_front(this);
101 Mode_list::Iterator i = modes.begin();
102 if (i != modes.end())
104 modes.insert_before(this, i);
109 void *get_head() const
110 { return Kobject::from_dbg(Kobject_dbg::begin()); }
113 Mode::Mode_list::Const_iterator _current_mode;
114 Filter_func *_filter;
117 //--------------------------------------------------------------------------
125 #include "entry_frame.h"
127 #include "jdb_core.h"
128 #include "jdb_module.h"
129 #include "jdb_screen.h"
130 #include "kernel_console.h"
132 #include "keycodes.h"
133 #include "ram_quota.h"
134 #include "simpleio.h"
136 #include "static_init.h"
138 Jdb_kobject_list::Mode::Mode_list Jdb_kobject_list::Mode::modes;
140 class Jdb_kobject_id_hdl : public Jdb_kobject_handler
143 virtual bool show_kobject(Kobject_common *, int) { return false; }
144 virtual ~Jdb_kobject_id_hdl() {}
149 Jdb_kobject_id_hdl::invoke(Kobject_common *o, Syscall_frame *f, Utcb *utcb)
151 if ( utcb->values[0] != Op_global_id
152 && utcb->values[0] != Op_kobj_to_id)
155 if (utcb->values[0] == Op_global_id)
156 utcb->values[0] = o->dbg_info()->dbg_id();
158 utcb->values[0] = Kobject_dbg::pointer_to_id((void *)utcb->values[1]);
159 f->tag(Kobject_iface::commit_result(0, 1));
166 Jdb_kobject_list::get_first()
168 Kobject_dbg::Iterator f = Kobject_dbg::begin();
169 while (f != Kobject_dbg::end() && _filter && !_filter(Kobject::from_dbg(f)))
171 return Kobject::from_dbg(f);
175 Jdb_kobject_list::Jdb_kobject_list(Filter_func *filt)
176 : Jdb_list(), _current_mode(Mode::modes.end()), _filter(filt)
177 { set_start(get_first()); }
180 Jdb_kobject_list::Jdb_kobject_list()
181 : Jdb_list(), _current_mode(Mode::modes.begin())
183 if (_current_mode != Mode::modes.end())
184 _filter = _current_mode->filter;
186 set_start(get_first());
191 Jdb_kobject_list::show_item(String_buffer *buffer, void *item) const
195 Jdb_kobject::obj_description(buffer, false, static_cast<Kobject*>(item)->dbg_info());
200 Jdb_kobject_list::enter_item(void *item) const
202 Kobject *o = static_cast<Kobject*>(item);
203 return Jdb_kobject::module()->handle_obj(o, 1);
208 Jdb_kobject_list::follow_link(void *item)
210 Kobject *o = static_cast<Kobject*>(item);
211 if (Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o))
212 return h->follow_link(o);
219 Jdb_kobject_list::handle_key(void *item, int keycode)
221 Kobject *o = static_cast<Kobject*>(item);
222 bool handled = false;
223 for (Jdb_kobject::Handler_iter h = Jdb_kobject::module()->global_handlers.begin();
224 h != Jdb_kobject::module()->global_handlers.end(); ++h)
225 handled |= h->handle_key(o, keycode);
227 if (Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o))
228 handled |= h->handle_key(o, keycode);
233 PRIVATE inline NOEXPORT
235 Jdb_kobject_list::next(Kobject *obj)
240 Kobject_dbg::Iterator o = Kobject_dbg::Kobject_list::iter(obj->dbg_info());
245 if (o == Kobject_dbg::end())
248 while (_filter && !_filter(Kobject::from_dbg(*o)));
249 return Kobject::from_dbg(*o);
252 PRIVATE inline NOEXPORT
254 Jdb_kobject_list::prev(Kobject *obj)
259 Kobject_dbg::Iterator o = Kobject_dbg::Kobject_list::iter(obj->dbg_info());
264 if (o == Kobject_dbg::end())
267 while (_filter && !_filter(Kobject::from_dbg(*o)));
268 return Kobject::from_dbg(*o);
273 Jdb_kobject_list::seek(int cnt, void **item)
275 Kobject *c = static_cast<Kobject*>(*item);
279 for (i = 0; i < cnt; ++i)
281 Kobject *n = next(c);
289 for (i = 0; i < -cnt; ++i)
291 Kobject *n = prev(c);
311 Jdb_kobject_list::show_head() const
319 Jdb_kobject_list::get_mode_str() const
321 if (_current_mode == Mode::modes.end())
323 return _current_mode->name;
330 Jdb_kobject_list::next_mode()
332 if (_current_mode == Mode::modes.end())
336 if (_current_mode == Mode::modes.end())
337 _current_mode = Mode::modes.begin();
339 _filter = _current_mode->filter;
342 /* When the mode changes the current object may get invisible,
343 * get a new visible one */
346 Jdb_kobject_list::get_valid(void *o)
351 if (_filter && _filter(static_cast<Kobject*>(o)))
358 Jdb_kobject_handler::invoke(Kobject_common *, Syscall_frame *, Utcb *)
361 void *Jdb_kobject::kobjp;
364 Jdb_kobject::Jdb_kobject()
371 Jdb_kobject::register_handler(Jdb_kobject_handler *h)
374 global_handlers.push_back(h);
376 handlers.push_back(h);
380 Jdb_kobject_handler *
381 Jdb_kobject::find_handler(Kobject_common *o)
383 for (Handler_iter h = handlers.begin(); h != handlers.end(); ++h)
385 auto r = o->_cxx_dyn_type();
386 if (r.type == h->kobj_type)
389 // XXX: may be we should sort the handlers: most derived first
390 cxx::uintptr_t delta;
391 if (r.type->do_cast(h->kobj_type, cxx::Typeid<Kobject_common>::get(),
392 (cxx::uintptr_t)o - (cxx::uintptr_t)r.base, &delta))
401 Jdb_kobject::handle_obj(Kobject *o, int lvl)
403 if (Jdb_kobject_handler *h = find_handler(o))
404 return h->show_kobject(o, lvl);
411 Jdb_kobject::kobject_type(Kobject_common *o)
413 if (Jdb_kobject_handler *h = module()->find_handler(o))
414 return h->kobject_type(o);
416 return Jdb_kobject_handler::_kobject_type(o);
422 Jdb_kobject::obj_description(String_buffer *buffer, bool dense, Kobject_dbg *o)
424 buffer->printf(dense ? "%lx %lx [%-*s]" : "%8lx %08lx [%-*s]",
425 o->dbg_id(), (Mword)Kobject::from_dbg(o), 7, kobject_type(Kobject::from_dbg(o)));
427 for (Handler_iter h = module()->global_handlers.begin();
428 h != module()->global_handlers.end(); ++h)
429 h->show_kobject_short(buffer, Kobject::from_dbg(o));
431 if (Jdb_kobject_handler *oh = Jdb_kobject::module()->find_handler(Kobject::from_dbg(o)))
432 oh->show_kobject_short(buffer, Kobject::from_dbg(o));
437 Jdb_kobject::print_kobj(Kobject *o)
439 printf("%p [type=%s]", o, cxx::dyn_typeid(o)->name);
443 Jdb_module::Action_code
444 Jdb_kobject::action(int cmd, void *&, char const *&, int &)
449 Kobject_dbg::Iterator i = Kobject_dbg::pointer_to_obj(kobjp);
450 if (i == Kobject_dbg::end())
451 printf("Not a kobj.\n");
454 Kobject *k = Kobject::from_dbg(i);
455 if (!handle_obj(k, 0))
456 printf("Kobj w/o handler: ");
464 Jdb_kobject_list list;
471 Jdb_module::Cmd const *
472 Jdb_kobject::cmds() const
476 { 0, "K", "kobj", "%p", "K<kobj_ptr>\tshow information for kernel object",
478 { 1, "Q", "listkobj", "", "Q\tshow information for kernel objects", 0 },
485 Jdb_kobject::num_cmds() const
488 STATIC_INITIALIZE_P(Jdb_kobject, JDB_MODULE_INIT_PRIO);
492 Jdb_kobject::fmt_handler(char /*fmt*/, int *size, char const *cmd_str, void *arg)
500 *size = sizeof(void*);
502 while((c = Jdb_core::cmd_getchar(cmd_str)) != ' ' && c!=KEY_RETURN)
507 if(c==KEY_BACKSPACE && pos>0)
513 if (pos < (int)sizeof(buffer) - 1)
515 Jdb_core::cmd_putchar(c);
521 Kobject **a = (Kobject**)arg;
529 char const *num = buffer;
530 if (buffer[0] == 'P')
533 n = strtoul(num, 0, 16);
535 Kobject_dbg::Iterator ko;
537 if (buffer[0] != 'P')
538 ko = Kobject_dbg::id_to_obj(n);
540 ko = Kobject_dbg::pointer_to_obj((void*)n);
542 if (ko != Kobject_dbg::end())
543 *a = Kobject::from_dbg(ko);
556 Jdb_core::add_fmt_handler('q', fmt_handler);
558 // static Jdb_handler enter(at_jdb_enter);
560 static Jdb_kobject_id_hdl id_hdl;
561 module()->register_handler(&id_hdl);
566 Jdb_kobject::module()
568 static Jdb_kobject jdb_kobj_module;
569 return &jdb_kobj_module;
572 // Be robust if this object is invalid
575 Jdb_kobject::print_uid(Kobject_common *o, int task_format = 0)
579 printf("%*.s", task_format, "---");
583 if (Kobject_dbg::is_kobj(o))
585 printf("%*.lx", task_format, o->dbg_info()->dbg_id());
589 printf("\033[31;1m%*s%p\033[m", task_format, "???", o);
595 sys_invoke_debug(Kobject_iface *o, Syscall_frame *f)
599 f->tag(Kobject_iface::commit_result(-L4_err::EInval));
603 Utcb *utcb = current_thread()->utcb().access();
604 //printf("sys_invoke_debug: [%p] -> %p\n", o, f);
605 Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o);
606 if (h && h->invoke(o, f, utcb))
609 for (Jdb_kobject::Handler_iter i = Jdb_kobject::module()->global_handlers.begin();
610 i != Jdb_kobject::module()->global_handlers.end(); ++i)
611 if (i->invoke(o, f, utcb))
614 f->tag(Kobject_iface::commit_result(-L4_err::ENosys));
618 template< typename T >
621 Jdb_kobject_extension::find_extension(Kobject_common const *o)
623 typedef Kobject_dbg::Dbg_ext_list::Iterator Iterator;
624 for (Iterator ex = o->dbg_info()->_jdb_data.begin();
625 ex != o->dbg_info()->_jdb_data.end(); ++ex)
627 Jdb_kobject_extension *je = static_cast<Jdb_kobject_extension*>(*ex);
628 if (je->type() == T::static_type)
629 return static_cast<T*>(je);
635 static Jdb_kobject_list::Mode INIT_PRIORITY(JDB_MODULE_INIT_PRIO) all("[ALL]", 0);