3 #include "jdb_module.h"
9 class Jdb_kobject_handler;
11 class Jdb_kobject : public Jdb_module
14 typedef cxx::S_list_tail<Jdb_kobject_handler> Handler_list;
15 typedef Handler_list::Const_iterator Handler_iter;
19 Handler_list handlers;
20 Handler_list global_handlers;
27 class Jdb_kobject_handler : public cxx::S_list_item
29 friend class Jdb_kobject;
32 Jdb_kobject_handler(char const *type) : kobj_type(type) {}
33 char const *kobj_type;
34 virtual bool show_kobject(Kobject_common *o, int level) = 0;
35 virtual int show_kobject_short(char *, int, Kobject_common *) { return 0; }
36 virtual Kobject_common *follow_link(Kobject_common *o) { return o; }
37 virtual ~Jdb_kobject_handler() {}
38 virtual bool invoke(Kobject_common *o, Syscall_frame *f, Utcb *utcb);
39 virtual bool handle_key(Kobject_common *, int /*keycode*/) { return false; }
40 virtual Kobject *parent(Kobject_common *) { return 0; }
41 virtual char const *kobject_type() const { return kobj_type; }
43 bool is_global() const { return !kobj_type; }
50 Op_query_log_typeid = 3,
53 Op_query_log_name = 6,
57 class Jdb_kobject_extension : public Kobject_dbg::Dbg_extension
60 virtual ~Jdb_kobject_extension() {}
61 virtual char const *type() const = 0;
64 class Jdb_kobject_list : public Jdb_list
67 typedef bool Filter_func(Kobject_common const *);
69 struct Mode : cxx::S_list_item
73 typedef cxx::S_list_bss<Mode> Mode_list;
74 static Mode_list modes;
76 Mode(char const *name, Filter_func *filter)
77 : name(name), filter(filter)
79 // make sure that non-filtered mode is first in the list so that we
80 // get this one displayed initially
82 modes.push_front(this);
85 Mode_list::Iterator i = modes.begin();
88 modes.insert_before(this, i);
93 void *get_head() const
94 { return Kobject::from_dbg(Kobject_dbg::begin()); }
97 Mode::Mode_list::Const_iterator _current_mode;
101 //--------------------------------------------------------------------------
109 #include "entry_frame.h"
111 #include "jdb_core.h"
112 #include "jdb_module.h"
113 #include "jdb_screen.h"
114 #include "kernel_console.h"
116 #include "keycodes.h"
117 #include "ram_quota.h"
118 #include "simpleio.h"
120 #include "static_init.h"
122 Jdb_kobject_list::Mode::Mode_list Jdb_kobject_list::Mode::modes;
124 class Jdb_kobject_id_hdl : public Jdb_kobject_handler
127 Jdb_kobject_id_hdl() : Jdb_kobject_handler(0) {}
128 virtual bool show_kobject(Kobject_common *, int) { return false; }
129 virtual ~Jdb_kobject_id_hdl() {}
134 Jdb_kobject_id_hdl::invoke(Kobject_common *o, Syscall_frame *f, Utcb *utcb)
136 if ( utcb->values[0] != Op_global_id
137 && utcb->values[0] != Op_kobj_to_id)
140 if (utcb->values[0] == Op_global_id)
141 utcb->values[0] = o->dbg_info()->dbg_id();
143 utcb->values[0] = Kobject_dbg::pointer_to_id((void *)utcb->values[1]);
144 f->tag(Kobject_iface::commit_result(0, 1));
151 Jdb_kobject_list::get_first()
153 Kobject_dbg::Iterator f = Kobject_dbg::begin();
154 while (f != Kobject_dbg::end() && _filter && !_filter(Kobject::from_dbg(f)))
156 return Kobject::from_dbg(f);
160 Jdb_kobject_list::Jdb_kobject_list(Filter_func *filt)
161 : Jdb_list(), _current_mode(Mode::modes.end()), _filter(filt)
162 { set_start(get_first()); }
165 Jdb_kobject_list::Jdb_kobject_list()
166 : Jdb_list(), _current_mode(Mode::modes.begin())
168 if (_current_mode != Mode::modes.end())
169 _filter = _current_mode->filter;
171 set_start(get_first());
176 Jdb_kobject_list::show_item(char *buffer, int max, void *item) const
178 return Jdb_kobject::obj_description(buffer, max, false, static_cast<Kobject*>(item)->dbg_info());
183 Jdb_kobject_list::enter_item(void *item) const
185 Kobject *o = static_cast<Kobject*>(item);
186 return Jdb_kobject::module()->handle_obj(o, 1);
191 Jdb_kobject_list::follow_link(void *item)
193 Kobject *o = static_cast<Kobject*>(item);
194 if (Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o))
195 return h->follow_link(o);
202 Jdb_kobject_list::handle_key(void *item, int keycode)
204 Kobject *o = static_cast<Kobject*>(item);
205 bool handled = false;
206 for (Jdb_kobject::Handler_iter h = Jdb_kobject::module()->global_handlers.begin();
207 h != Jdb_kobject::module()->global_handlers.end(); ++h)
208 handled |= h->handle_key(o, keycode);
210 if (Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o))
211 handled |= h->handle_key(o, keycode);
216 PRIVATE inline NOEXPORT
218 Jdb_kobject_list::next(Kobject *obj)
223 Kobject_dbg::Iterator o = Kobject_dbg::Kobject_list::iter(obj->dbg_info());
228 if (o == Kobject_dbg::end())
231 while (_filter && !_filter(Kobject::from_dbg(*o)));
232 return Kobject::from_dbg(*o);
235 PRIVATE inline NOEXPORT
237 Jdb_kobject_list::prev(Kobject *obj)
242 Kobject_dbg::Iterator o = Kobject_dbg::Kobject_list::iter(obj->dbg_info());
247 if (o == Kobject_dbg::end())
250 while (_filter && !_filter(Kobject::from_dbg(*o)));
251 return Kobject::from_dbg(*o);
256 Jdb_kobject_list::seek(int cnt, void **item)
258 Kobject *c = static_cast<Kobject*>(*item);
262 for (i = 0; i < cnt; ++i)
264 Kobject *n = next(c);
272 for (i = 0; i < -cnt; ++i)
274 Kobject *n = prev(c);
294 Jdb_kobject_list::show_head() const
302 Jdb_kobject_list::get_mode_str() const
304 if (_current_mode == Mode::modes.end())
306 return _current_mode->name;
313 Jdb_kobject_list::next_mode()
315 if (_current_mode == Mode::modes.end())
319 if (_current_mode == Mode::modes.end())
320 _current_mode = Mode::modes.begin();
322 _filter = _current_mode->filter;
325 /* When the mode changes the current object may get invisible,
326 * get a new visible one */
329 Jdb_kobject_list::get_valid(void *o)
334 if (_filter && _filter(static_cast<Kobject*>(o)))
341 Jdb_kobject_handler::invoke(Kobject_common *, Syscall_frame *, Utcb *)
344 void *Jdb_kobject::kobjp;
347 Jdb_kobject::Jdb_kobject()
354 Jdb_kobject::register_handler(Jdb_kobject_handler *h)
357 global_handlers.push_back(h);
359 handlers.push_back(h);
363 Jdb_kobject_handler *
364 Jdb_kobject::find_handler(Kobject_common *o)
366 for (Handler_iter h = handlers.begin(); h != handlers.end(); ++h)
367 if (o->kobj_type() == h->kobj_type)
375 Jdb_kobject::handle_obj(Kobject *o, int lvl)
377 if (Jdb_kobject_handler *h = find_handler(o))
378 return h->show_kobject(o, lvl);
385 Jdb_kobject::kobject_type(Kobject_common *o)
387 if (Jdb_kobject_handler *h = module()->find_handler(o))
388 return h->kobject_type();
390 return o->kobj_type();
396 Jdb_kobject::obj_description(char *buffer, int max, bool dense, Kobject_dbg *o)
398 int pos = snprintf(buffer, max,
399 dense ? "%lx %lx [%-*s]" : "%8lx %08lx [%-*s]",
400 o->dbg_id(), (Mword)Kobject::from_dbg(o), 7, kobject_type(Kobject::from_dbg(o)));
402 for (Handler_iter h = module()->global_handlers.begin();
403 h != module()->global_handlers.end(); ++h)
404 pos += h->show_kobject_short(buffer + pos, max-pos, Kobject::from_dbg(o));
406 if (Jdb_kobject_handler *oh = Jdb_kobject::module()->find_handler(Kobject::from_dbg(o)))
407 pos += oh->show_kobject_short(buffer + pos, max-pos, Kobject::from_dbg(o));
414 Jdb_kobject::print_kobj(Kobject *o)
416 printf("%p [type=%s]", o, o->kobj_type());
420 Jdb_module::Action_code
421 Jdb_kobject::action(int cmd, void *&, char const *&, int &)
426 Kobject_dbg::Iterator i = Kobject_dbg::pointer_to_obj(kobjp);
427 if (i == Kobject_dbg::end())
428 printf("Not a kobj.\n");
431 Kobject *k = Kobject::from_dbg(i);
432 if (!handle_obj(k, 0))
433 printf("Kobj w/o handler: ");
441 Jdb_kobject_list list;
448 Jdb_module::Cmd const *
449 Jdb_kobject::cmds() const
453 { 0, "K", "kobj", "%p", "K<kobj_ptr>\tshow information for kernel object",
455 { 1, "Q", "listkobj", "", "Q\tshow information for kernel objects", 0 },
462 Jdb_kobject::num_cmds() const
465 STATIC_INITIALIZE_P(Jdb_kobject, JDB_MODULE_INIT_PRIO);
469 Jdb_kobject::fmt_handler(char /*fmt*/, int *size, char const *cmd_str, void *arg)
477 *size = sizeof(void*);
479 while((c = Jdb_core::cmd_getchar(cmd_str)) != ' ' && c!=KEY_RETURN)
484 if(c==KEY_BACKSPACE && pos>0)
490 if (pos < (int)sizeof(buffer) - 1)
498 Kobject **a = (Kobject**)arg;
506 char const *num = buffer;
507 if (buffer[0] == 'P')
510 n = strtoul(num, 0, 16);
512 Kobject_dbg::Iterator ko;
514 if (buffer[0] != 'P')
515 ko = Kobject_dbg::id_to_obj(n);
517 ko = Kobject_dbg::pointer_to_obj((void*)n);
519 if (ko != Kobject_dbg::end())
520 *a = Kobject::from_dbg(ko);
533 Jdb_core::add_fmt_handler('q', fmt_handler);
535 // static Jdb_handler enter(at_jdb_enter);
537 static Jdb_kobject_id_hdl id_hdl;
538 module()->register_handler(&id_hdl);
543 Jdb_kobject::module()
545 static Jdb_kobject jdb_kobj_module;
546 return &jdb_kobj_module;
549 // Be robust if this object is invalid
552 Jdb_kobject::print_uid(Kobject_common *o, int task_format = 0)
556 printf("%*.s", task_format, "---");
560 if (Kobject_dbg::is_kobj(o))
562 printf("%*.lx", task_format, o->dbg_info()->dbg_id());
566 printf("\033[31;1m%*s%p\033[m", task_format, "???", o);
572 sys_invoke_debug(Kobject_iface *o, Syscall_frame *f)
576 f->tag(Kobject_iface::commit_result(-L4_err::EInval));
580 Utcb *utcb = current_thread()->utcb().access();
581 //printf("sys_invoke_debug: [%p] -> %p\n", o, f);
582 Jdb_kobject_handler *h = Jdb_kobject::module()->find_handler(o);
583 if (h && h->invoke(o, f, utcb))
586 for (Jdb_kobject::Handler_iter i = Jdb_kobject::module()->global_handlers.begin();
587 i != Jdb_kobject::module()->global_handlers.end(); ++i)
588 if (i->invoke(o, f, utcb))
591 f->tag(Kobject_iface::commit_result(-L4_err::ENosys));
595 template< typename T >
598 Jdb_kobject_extension::find_extension(Kobject_common const *o)
600 typedef Kobject_dbg::Dbg_ext_list::Iterator Iterator;
601 for (Iterator ex = o->dbg_info()->_jdb_data.begin();
602 ex != o->dbg_info()->_jdb_data.end(); ++ex)
604 Jdb_kobject_extension *je = static_cast<Jdb_kobject_extension*>(*ex);
605 if (je->type() == T::static_type)
606 return static_cast<T*>(je);
612 static Jdb_kobject_list::Mode INIT_PRIORITY(JDB_MODULE_INIT_PRIO) all("[ALL]", 0);