Commit 7ff9554bb578 ("printk: convert byte-buffer to variable-length record buffer") introduced a record based printk buffer. Modify gdbmacros.txt to parse this new structure so dmesg will work properly.
Unified · Split
| @@ -170,21 +170,92 @@ document trapinfo · 169 unmodified lines | ||
| 170 | 170 | address the kernel panicked. |
| 171 | 171 | end |
| 172 | 172 | |
| 173 | +define dump_log_idx | |
| 174 | + set $idx = $arg0 | |
| 175 | + if ($argc > 1) | |
| 176 | + set $prev_flags = $arg1 | |
| 177 | + else | |
| 178 | + set $prev_flags = 0 | |
| 179 | + end | |
| 180 | + set $msg = ((struct printk_log *) (log_buf + $idx)) | |
| 181 | + set $prefix = 1 | |
| 182 | + set $newline = 1 | |
| 183 | + set $log = log_buf + $idx + sizeof(*$msg) | |
| 173 | 184 | |
| 174 | −define dmesg | |
| 175 | − set $i = 0 | |
| 176 | − set $end_idx = (log_end - 1) & (log_buf_len - 1) | |
| 185 | + # prev & LOG_CONT && !(msg->flags & LOG_PREIX) | |
| 186 | + if (($prev_flags & 8) && !($msg->flags & 4)) | |
| 187 | + set $prefix = 0 | |
| 188 | + end | |
| 189 | + | |
| 190 | + # msg->flags & LOG_CONT | |
| 191 | + if ($msg->flags & 8) | |
| 192 | + # (prev & LOG_CONT && !(prev & LOG_NEWLINE)) | |
| 193 | + if (($prev_flags & 8) && !($prev_flags & 2)) | |
| 194 | + set $prefix = 0 | |
| 195 | + end | |
| 196 | + # (!(msg->flags & LOG_NEWLINE)) | |
| 197 | + if (!($msg->flags & 2)) | |
| 198 | + set $newline = 0 | |
| 199 | + end | |
| 200 | + end | |
| 201 | + | |
| 202 | + if ($prefix) | |
| 203 | + printf "[%5lu.%06lu] ", $msg->ts_nsec / 1000000000, $msg->ts_nsec % 1000000000 | |
| 204 | + end | |
| 205 | + if ($msg->text_len != 0) | |
| 206 | + eval "printf \"%%%d.%ds\", $log", $msg->text_len, $msg->text_len | |
| 207 | + end | |
| 208 | + if ($newline) | |
| 209 | + printf "\n" | |
| 210 | + end | |
| 211 | + if ($msg->dict_len > 0) | |
| 212 | + set $dict = $log + $msg->text_len | |
| 213 | + set $idx = 0 | |
| 214 | + set $line = 1 | |
| 215 | + while ($idx < $msg->dict_len) | |
| 216 | + if ($line) | |
| 217 | + printf " " | |
| 218 | + set $line = 0 | |
| 219 | + end | |
| 220 | + set $c = $dict[$idx] | |
| 221 | + if ($c == '\0') | |
| 222 | + printf "\n" | |
| 223 | + set $line = 1 | |
| 224 | + else | |
| 225 | + if ($c < ' ' || $c >= 127 || $c == '\\') | |
| 226 | + printf "\\x%02x", $c | |
| 227 | + else | |
| 228 | + printf "%c", $c | |
| 229 | + end | |
| 230 | + end | |
| 231 | + set $idx = $idx + 1 | |
| 232 | + end | |
| 233 | + printf "\n" | |
| 234 | + end | |
| 235 | +end | |
| 236 | +document dump_log_idx | |
| 237 | + Dump a single log given its index in the log buffer. The first | |
| 238 | + parameter is the index into log_buf, the second is optional and | |
| 239 | + specified the previous log buffer's flags, used for properly | |
| 240 | + formatting continued lines. | |
| 241 | +end | |
| 177 | 242 | |
| 178 | − while ($i < logged_chars) | |
| 179 | − set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1) | |
| 243 | +define dmesg | |
| 244 | + set $i = log_first_idx | |
| 245 | + set $end_idx = log_first_idx | |
| 246 | + set $prev_flags = 0 | |
| 180 | 247 | |
| 181 | − if ($idx + 100 <= $end_idx) || \ | |
| 182 | − ($end_idx <= $idx && $idx + 100 < log_buf_len) | |
| 183 | − printf "%.100s", &log_buf[$idx] | |
| 184 | − set $i = $i + 100 | |
| 248 | + while (1) | |
| 249 | + set $msg = ((struct printk_log *) (log_buf + $i)) | |
| 250 | + if ($msg->len == 0) | |
| 251 | + set $i = 0 | |
| 185 | 252 | else |
| 186 | − printf "%c", log_buf[$idx] | |
| 187 | − set $i = $i + 1 | |
| 253 | + dump_log_idx $i $prev_flags | |
| 254 | + set $i = $i + $msg->len | |
| 255 | + set $prev_flags = $msg->flags | |
| 256 | + end | |
| 257 | + if ($i == $end_idx) | |
| 258 | + loop_break | |
| 188 | 259 | end |
| 189 | 260 | end |
| 190 | 261 | end |