瀏覽代碼

Kernel: Fix crash when changing screen resolution

Steps to reproduce:

1. Change resolution to 640x480.
2. Change resolution to 1280x1024.
3. Observe the following kernel panic:

Kernel::__panic(char const*, unsigned int, char const*) +0x55
Kernel::handle_crash(Kernel::RegisterState&, char const*, ...) +0x112
page_fault_handler +0x1130
page_fault_asm_entry +0x26
Kernel::VirtualConsole::refresh_after_resolution_change() +0x35e4
Kernel::ConsoleManagement::resolution_was_changed() +0x38b
Kernel::Graphics::FramebufferConsole::set_resolution(...) +0x3e1
Kernel::BochsGraphicsAdapter::try_to_set_resolution(...) +0x319
.L4213 +0x40a
Kernel::Process::sys$ioctl(int, unsigned int, unsigned int) +0x2fa
Kernel::Syscall::handle(Kernel::RegisterState&, ...) +0xfdc
syscall_handler +0x19c0
Kernel::syscall_asm_entry_dummy() +0x31
Gunnar Beutner 4 年之前
父節點
當前提交
22b0cbe1fe
共有 1 個文件被更改,包括 6 次插入13 次删除
  1. 6 13
      Kernel/TTY/VirtualConsole.cpp

+ 6 - 13
Kernel/TTY/VirtualConsole.cpp

@@ -151,19 +151,12 @@ void VirtualConsole::refresh_after_resolution_change()
     }
 
     // Note: A potential loss of displayed data occur when resolution width shrinks.
-    if (columns() < old_columns_count) {
-        for (size_t row = 0; row < rows(); row++) {
-            auto& line = m_lines[row];
-            memcpy(new_cells->vaddr().offset((row)*columns() * sizeof(Cell)).as_ptr(), m_cells->vaddr().offset((row) * (old_columns_count) * sizeof(Cell)).as_ptr(), columns() * sizeof(Cell));
-            line.dirty = true;
-        }
-    } else {
-        // Handle Growth of resolution
-        for (size_t row = 0; row < rows(); row++) {
-            auto& line = m_lines[row];
-            memcpy(new_cells->vaddr().offset((row)*columns() * sizeof(Cell)).as_ptr(), m_cells->vaddr().offset((row) * (old_columns_count) * sizeof(Cell)).as_ptr(), old_columns_count * sizeof(Cell));
-            line.dirty = true;
-        }
+    auto common_rows_count = min(old_rows_count, rows());
+    auto common_columns_count = min(old_columns_count, columns());
+    for (size_t row = 0; row < common_rows_count; row++) {
+        auto& line = m_lines[row];
+        memcpy(new_cells->vaddr().offset(row * columns() * sizeof(Cell)).as_ptr(), m_cells->vaddr().offset(row * old_columns_count * sizeof(Cell)).as_ptr(), common_columns_count * sizeof(Cell));
+        line.dirty = true;
     }
 
     // Update the new cells Region