13 typedef void (Format_entry_fn)(String_buffer *, Tb_entry *tb, const char *tidstr,
15 static Format_entry_fn *_format_entry_fn[];
16 static bool show_names;
27 #include "initcalls.h"
29 #include "jdb_kobject_names.h"
30 #include "jdb_regex.h"
31 #include "jdb_symbol.h"
34 #include "kernel_console.h"
36 #include "processor.h"
37 #include "static_init.h"
38 #include "string_buffer.h"
40 #include "terminate.h"
44 Jdb_tbuf_output::Format_entry_fn *Jdb_tbuf_output::_format_entry_fn[Tbuf_dynentries];
45 bool Jdb_tbuf_output::show_names;
48 console_log_entry(Tb_entry *e, const char *)
50 static String_buf<80> log_message;
53 // disable all interrupts to stop other threads
55 Proc::Status s = Proc::cli_save();
57 Jdb_tbuf_output::print_entry(&log_message, e);
58 printf("%s\n", log_message.begin());
60 // do not use getchar here because we ran cli'd
61 // and getchar may do halt
64 while ((c=Kconsole::console()->getchar(false)) == -1)
72 // enable interrupts we previously disabled
79 Jdb_tbuf_output::dummy_format_entry(String_buffer *buf, Tb_entry *tb, const char *, int)
81 buf->printf(" << no format_entry_fn for type %d registered >>", tb->type());
84 STATIC_INITIALIZE(Jdb_tbuf_output);
88 Jdb_tbuf_output::init()
92 Jdb_tbuf::direct_log_entry = &console_log_entry;
93 for (i=0; i<sizeof(_format_entry_fn)/sizeof(_format_entry_fn[0]); i++)
94 if (!_format_entry_fn[i])
95 _format_entry_fn[i] = dummy_format_entry;
100 Jdb_tbuf_output::register_ff(Unsigned8 type, Format_entry_fn format_entry_fn)
102 assert(type < Tbuf_dynentries);
104 if ( (_format_entry_fn[type] != 0)
105 && (_format_entry_fn[type] != dummy_format_entry))
106 panic("format entry function for type %d already registered", type);
108 _format_entry_fn[type] = format_entry_fn;
111 // return thread+ip of entry <e_nr>
114 Jdb_tbuf_output::thread_ip(int e_nr, Thread const **th, Mword *ip)
116 Tb_entry *e = Jdb_tbuf::lookup(e_nr);
121 *th = static_cast<Thread const *>(e->ctx());
130 Jdb_tbuf_output::toggle_names()
132 show_names = !show_names;
137 formatter_default(String_buffer *buf, Tb_entry *tb, const char *tidstr, int tidlen)
139 if (tb->type() < Tbuf_dynentries)
142 int idx = tb->type()-Tbuf_dynentries;
144 Tb_entry_formatter *fmt = _log_table[idx].fmt;
145 char const *sc = _log_table[idx].name;
146 sc += strlen(sc) + 1;
148 buf->printf("%-3s: %-*s ", sc, tidlen, tidstr);
152 Tb_entry_ke_reg *e = static_cast<Tb_entry_ke_reg*>(tb);
153 buf->printf("\"%s\" " L4_PTR_FMT " " L4_PTR_FMT " " L4_PTR_FMT " @ " L4_PTR_FMT,
154 e->msg.str(), e->v[0], e->v[1], e->v[2], e->ip());
162 Jdb_tbuf_output::print_entry(String_buffer *buf, int e_nr)
164 Tb_entry *tb = Jdb_tbuf::lookup(e_nr);
167 print_entry(buf, tb);
172 Jdb_tbuf_output::print_entry(String_buffer *buf, Tb_entry *tb)
174 assert(tb->type() < Tbuf_max);
177 Thread const *t = static_cast<Thread const *>(tb->ctx());
179 if (!t || !Kobject_dbg::is_kobj(t))
180 strcpy(tidstr, "????");
184 = Jdb_kobject_extension::find_extension<Jdb_kobject_name>(t);
185 if (show_names && ex)
186 snprintf(tidstr, sizeof(tidstr), "%04lx %-*.*s", t->dbg_info()->dbg_id(), (int)ex->max_len(), (int)ex->max_len(), ex->name());
188 snprintf(tidstr, sizeof(tidstr), "%04lx", t->dbg_info()->dbg_id());
191 if (Config::Max_num_cpus > 1)
192 buf->printf(Config::Max_num_cpus > 16 ? "%02d " : "%d ", tb->cpu());
194 if (tb->type() >= Tbuf_dynentries)
195 formatter_default(buf, tb, tidstr, show_names ? 21 : 4);
197 _format_entry_fn[tb->type()](buf, tb, tidstr, show_names ? 21 : 4);
205 Jdb_tbuf_output::set_filter(const char *filter_str, Mword *entries)
207 if (*filter_str && Jdb_regex::avail() && !Jdb_regex::start(filter_str))
212 for (Mword n=0; n<Jdb_tbuf::unfiltered_entries(); n++)
213 Jdb_tbuf::unfiltered_lookup(n)->unhide();
215 Jdb_tbuf::disable_filter();
217 *entries = Jdb_tbuf::unfiltered_entries();
223 for (Mword n=0; n<Jdb_tbuf::unfiltered_entries(); n++)
225 Tb_entry *e = Jdb_tbuf::unfiltered_lookup(n);
229 if (Jdb_regex::avail())
231 if (Jdb_regex::find(s.begin(), 0, 0))
240 if (strstr(s.begin(), filter_str))
252 Jdb_tbuf::enable_filter();