From 8352069285400300fdc80a832feba51cd710fce4 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 27 Apr 2024 19:02:37 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3string=E5=92=8Cvec=E7=9A=84bu?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debug/2024-04.txt | 28 +++++++++- src/libk/alloc/string.rs | 108 ++++++++++++++++++++++++++++++++++++--- src/libk/alloc/vec.rs | 34 ++++++------ src/libk/core/mod.rs | 1 + src/libk/core/ptr/mod.rs | 30 +++++++++++ 5 files changed, 176 insertions(+), 25 deletions(-) create mode 100644 src/libk/core/ptr/mod.rs diff --git a/debug/2024-04.txt b/debug/2024-04.txt index 914d7c4..565e054 100644 --- a/debug/2024-04.txt +++ b/debug/2024-04.txt @@ -17,7 +17,7 @@ Stack trace: 使用了core crate中的String,导致最终调用了一个含有未正确链接的函数。 ======== 04-23 13:55 ======== -Hit null pointer as 0x100351a. +Hit null pointer at 0x100351a. Stack trace: 0x00000000010054d0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut 0x0000000001006170 -> ::to_string @@ -27,3 +27,29 @@ Stack trace: 0x0000000001003f60 -> alloc::alloc::alloc 0x00000000010034f0 -> core::ptr::read_volatile::precondition_check 使用了core crate的alloc函数,其中含有未正确链接的函数。 + +======== 04-26 02:56 ======== +Hit null pointer in metaverse::libk::alloc::string::String::clone() +Stack trace: + 0x0000000001005520 -> metaverse::kernel::tty::tty::format_message + 0x00000000010052f0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut + 0x00000000010073f0 -> ::to_string + 0x0000000001009a90 -> ::clone +使用了Clone的derive宏,含有未正确链接的函数。 + +======== 04-26 15:55 ======== +Hit null pointer at 0x1003672. +Stack trace: + 0x0000000001007600 -> ::to_string + 0x0000000001007030 -> metaverse::libk::alloc::string::String::insert + 0x0000000001008330 -> metaverse::libk::alloc::vec::Vec::insert + 0x0000000001007950 -> metaverse::libk::alloc::vec::Vec::extend_capacity + 0x0000000001003630 -> core::intrinsics::copy::precondition_check +将*mut u8转换为*mut T时调用了此函数,导致调用了一个未正确链接的函数。 + +======== 04-27 16:06 ======== +Trapped into a infinite loop. +Stack trace: + 0x0000000001006c30 -> interrupt_req_DE + 0x0000000001005420 -> metaverse::kernel::tty::tty::MessageBuilder::append + 0x0000000001008410 -> metaverse::libk::alloc::vec::Vec::append diff --git a/src/libk/alloc/string.rs b/src/libk/alloc/string.rs index c106e0c..1676e4f 100644 --- a/src/libk/alloc/string.rs +++ b/src/libk/alloc/string.rs @@ -2,7 +2,7 @@ use core::ops::{Add, AddAssign}; use super::vec::{Vec, VecIterator}; -#[derive(Clone, Default)] +#[derive(Default)] pub struct String { data: Vec, u8data: Vec, @@ -75,6 +75,15 @@ impl AddAssign for String { } } +impl Clone for String { + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + u8data: self.u8data.clone(), + } + } +} + pub trait ToString { fn to_string(&self) -> String; fn to_octal_string(&self) -> String { @@ -129,7 +138,7 @@ impl ToString for u8 { let mut num = *self; let mut res = String::new(); while num != 0 { - res.insert(0, (tohex(num % 16) + b'0') as char); + res.insert(0, tohex(num % 16) as char); num /= 16; } res @@ -144,6 +153,9 @@ impl ToString for u16 { res.insert(0, ((num % 10) as u8 + b'0') as char); num /= 10; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -154,6 +166,9 @@ impl ToString for u16 { res.insert(0, ((num % 8) as u8 + b'0') as char); num /= 8; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -168,12 +183,16 @@ impl ToString for u16 { let mut num = *self; let mut res = String::new(); while num != 0 { - res.insert(0, (tohex(num % 16) + b'0') as char); + res.insert(0, tohex(num % 16) as char); num /= 16; } + if res.len() == 0 { + res.insert(0, '0'); + } res } } + impl ToString for u32 { fn to_string(&self) -> String { let mut num = *self; @@ -182,6 +201,9 @@ impl ToString for u32 { res.insert(0, ((num % 10) as u8 + b'0') as char); num /= 10; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -192,6 +214,9 @@ impl ToString for u32 { res.insert(0, ((num % 8) as u8 + b'0') as char); num /= 8; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -206,12 +231,16 @@ impl ToString for u32 { let mut num = *self; let mut res = String::new(); while num != 0 { - res.insert(0, (tohex(num % 16) + b'0') as char); + res.insert(0, tohex(num % 16) as char); num /= 16; } + if res.len() == 0 { + res.insert(0, '0'); + } res } } + impl ToString for u64 { fn to_string(&self) -> String { let mut num = *self; @@ -220,6 +249,9 @@ impl ToString for u64 { res.insert(0, ((num % 10) as u8 + b'0') as char); num /= 10; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -230,6 +262,9 @@ impl ToString for u64 { res.insert(0, ((num % 8) as u8 + b'0') as char); num /= 8; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -244,12 +279,16 @@ impl ToString for u64 { let mut num = *self; let mut res = String::new(); while num != 0 { - res.insert(0, (tohex(num % 16) + b'0') as char); + res.insert(0, tohex(num % 16) as char); num /= 16; } + if res.len() == 0 { + res.insert(0, '0'); + } res } } + impl ToString for u128 { fn to_string(&self) -> String { let mut num = *self; @@ -258,6 +297,9 @@ impl ToString for u128 { res.insert(0, ((num % 10) as u8 + b'0') as char); num /= 10; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -268,6 +310,9 @@ impl ToString for u128 { res.insert(0, ((num % 8) as u8 + b'0') as char); num /= 8; } + if res.len() == 0 { + res.insert(0, '0'); + } res } @@ -282,9 +327,60 @@ impl ToString for u128 { let mut num = *self; let mut res = String::new(); while num != 0 { - res.insert(0, (tohex(num % 16) + b'0') as char); + res.insert(0, tohex(num % 16) as char); num /= 16; } + if res.len() == 0 { + res.insert(0, '0'); + } + res + } +} + +impl ToString for usize { + fn to_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 10) as u8 + b'0') as char); + num /= 10; + } + if res.len() == 0 { + res.insert(0, '0'); + } + res + } + + fn to_octal_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 8) as u8 + b'0') as char); + num /= 8; + } + if res.len() == 0 { + res.insert(0, '0'); + } + res + } + + fn to_hex_string(&self) -> String { + let tohex = |x| { + if x < 10 { + x as u8 + b'0' + } else { + x as u8 - 10 + b'a' + } + }; + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, tohex(num % 16) as char); + num /= 16; + } + if res.len() == 0 { + res.insert(0, '0'); + } res } } diff --git a/src/libk/alloc/vec.rs b/src/libk/alloc/vec.rs index 66df0b2..a33e2dc 100644 --- a/src/libk/alloc/vec.rs +++ b/src/libk/alloc/vec.rs @@ -1,11 +1,14 @@ use core::{ alloc::Layout, ops::{Index, IndexMut, Range, RangeFull}, - ptr::{addr_of_mut, null_mut}, + ptr::addr_of_mut, slice, }; -use crate::libk::alloc::alloc::{alloc, dealloc}; +use crate::libk::{ + alloc::alloc::{alloc, dealloc}, + core::ptr::PtrOptions, +}; pub struct Vec { pointer: *mut T, @@ -16,15 +19,15 @@ pub struct Vec { impl Vec { pub fn new() -> Self { Self { - pointer: null_mut(), + pointer: unsafe { alloc(Layout::array::(4).unwrap()).cast() }, length: 0, - capacity: 0, + capacity: 4, } } unsafe fn extend_capacity(&mut self) { - let newp = alloc(Layout::array::(self.capacity * 2).unwrap()).cast(); - self.pointer.copy_to(newp, self.length); + let newp: *mut T = alloc(Layout::array::(self.capacity * 2).unwrap()).cast(); + self.pointer.kcopy_to(newp, self.length); dealloc( self.pointer.cast(), Layout::array::(self.capacity).unwrap(), @@ -34,11 +37,6 @@ impl Vec { } pub fn push(&mut self, item: T) { - if self.pointer.is_null() { - self.pointer = unsafe { alloc(Layout::array::(4).unwrap()).cast() }; - self.capacity = 4; - self.length = 0; - } if self.capacity == self.length { unsafe { self.extend_capacity() } } @@ -54,11 +52,11 @@ impl Vec { unsafe { if rearlen != 0 { let tmp = alloc(Layout::array::(rearlen).unwrap()).cast(); - self.pointer.offset(index as isize).copy_to(tmp, rearlen); + self.pointer.offset(index as isize).kcopy_to(tmp, rearlen); self.pointer.offset(index as isize).write(item); self.pointer .offset(index as isize + 1) - .copy_from(tmp, rearlen); + .kcopy_from(tmp, rearlen); } else { self.pointer.offset(self.length as isize).write(item); } @@ -73,7 +71,7 @@ impl Vec { unsafe { self.pointer .offset(self.length as isize) - .copy_from(v.pointer.cast_const(), v.length) + .kcopy_from(v.pointer.cast_const(), v.length) }; self.length += v.length; } @@ -108,8 +106,8 @@ impl Vec { let mut t: T = T::default(); let pt = addr_of_mut!(t); unsafe { - pt.copy_from(self.pointer.offset(index as isize).cast_const(), 1); - self.pointer.offset(index as isize).copy_from( + pt.kcopy_from(self.pointer.offset(index as isize).cast_const(), 1); + self.pointer.offset(index as isize).kcopy_from( self.pointer.offset(index as isize + 1), self.length - index - 1, ); @@ -172,7 +170,7 @@ impl Clone for Vec { }; unsafe { res.pointer - .copy_from(self.pointer.cast_const(), self.length) + .kcopy_from(self.pointer.cast_const(), self.length) }; res } @@ -264,7 +262,7 @@ impl Iterator for VecIter { let res = unsafe { self.pointer .offset(self.index as isize) - .copy_to(addr_of_mut!(t), 1); + .kcopy_to(addr_of_mut!(t), 1); Some(t) }; self.index += 1; diff --git a/src/libk/core/mod.rs b/src/libk/core/mod.rs index e69de29..d0511c6 100644 --- a/src/libk/core/mod.rs +++ b/src/libk/core/mod.rs @@ -0,0 +1 @@ +pub mod ptr; \ No newline at end of file diff --git a/src/libk/core/ptr/mod.rs b/src/libk/core/ptr/mod.rs new file mode 100644 index 0000000..4341346 --- /dev/null +++ b/src/libk/core/ptr/mod.rs @@ -0,0 +1,30 @@ +use core::mem::{size_of, transmute}; + +extern "C" { + pub fn memset(des: *const u8, src: u8, len: usize); + pub fn memcpy(des: *const u8, src: *const u8, len: usize); + pub fn strlen(des: *const u8) -> usize; +} + +pub trait PtrOptions { + unsafe fn kcopy_from(self, src: *const T, count: usize); + unsafe fn kcopy_to(self, des: *const T, count: usize); +} + +impl PtrOptions for *mut T { + unsafe fn kcopy_from(self, src: *const T, count: usize) { + memcpy( + transmute(self.cast_const()), + transmute(src), + count * size_of::(), + ); + } + + unsafe fn kcopy_to(self, des: *const T, count: usize) { + memcpy( + transmute(des), + transmute(self.cast_const()), + count * size_of::(), + ); + } +}