解决string和vec的bug

This commit is contained in:
pointer-to-bios 2024-04-27 19:02:37 +08:00
parent f2240787b6
commit 8352069285
5 changed files with 176 additions and 25 deletions

View File

@ -17,7 +17,7 @@ Stack trace:
使用了core crate中的String导致最终调用了一个含有未正确链接的函数。 使用了core crate中的String导致最终调用了一个含有未正确链接的函数。
======== 04-23 13:55 ======== ======== 04-23 13:55 ========
Hit null pointer as 0x100351a. Hit null pointer at 0x100351a.
Stack trace: Stack trace:
0x00000000010054d0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut 0x00000000010054d0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut
0x0000000001006170 -> <str as metaverse::libk::alloc::string::ToString>::to_string 0x0000000001006170 -> <str as metaverse::libk::alloc::string::ToString>::to_string
@ -27,3 +27,29 @@ Stack trace:
0x0000000001003f60 -> alloc::alloc::alloc 0x0000000001003f60 -> alloc::alloc::alloc
0x00000000010034f0 -> core::ptr::read_volatile::precondition_check 0x00000000010034f0 -> core::ptr::read_volatile::precondition_check
使用了core crate的alloc函数其中含有未正确链接的函数。 使用了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 -> <metaverse::libk::alloc::string::String as metaverse::libk::alloc::string::ToString>::to_string
0x0000000001009a90 -> <metaverse::libk::alloc::string::String as core::clone::Clone>::clone
使用了Clone的derive宏含有未正确链接的函数。
======== 04-26 15:55 ========
Hit null pointer at 0x1003672.
Stack trace:
0x0000000001007600 -> <u64 as metaverse::libk::alloc::string::ToString>::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

View File

@ -2,7 +2,7 @@ use core::ops::{Add, AddAssign};
use super::vec::{Vec, VecIterator}; use super::vec::{Vec, VecIterator};
#[derive(Clone, Default)] #[derive(Default)]
pub struct String { pub struct String {
data: Vec<char>, data: Vec<char>,
u8data: Vec<u8>, u8data: Vec<u8>,
@ -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 { pub trait ToString {
fn to_string(&self) -> String; fn to_string(&self) -> String;
fn to_octal_string(&self) -> String { fn to_octal_string(&self) -> String {
@ -129,7 +138,7 @@ impl ToString for u8 {
let mut num = *self; let mut num = *self;
let mut res = String::new(); let mut res = String::new();
while num != 0 { while num != 0 {
res.insert(0, (tohex(num % 16) + b'0') as char); res.insert(0, tohex(num % 16) as char);
num /= 16; num /= 16;
} }
res res
@ -144,6 +153,9 @@ impl ToString for u16 {
res.insert(0, ((num % 10) as u8 + b'0') as char); res.insert(0, ((num % 10) as u8 + b'0') as char);
num /= 10; num /= 10;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -154,6 +166,9 @@ impl ToString for u16 {
res.insert(0, ((num % 8) as u8 + b'0') as char); res.insert(0, ((num % 8) as u8 + b'0') as char);
num /= 8; num /= 8;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -168,12 +183,16 @@ impl ToString for u16 {
let mut num = *self; let mut num = *self;
let mut res = String::new(); let mut res = String::new();
while num != 0 { while num != 0 {
res.insert(0, (tohex(num % 16) + b'0') as char); res.insert(0, tohex(num % 16) as char);
num /= 16; num /= 16;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
} }
impl ToString for u32 { impl ToString for u32 {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let mut num = *self; let mut num = *self;
@ -182,6 +201,9 @@ impl ToString for u32 {
res.insert(0, ((num % 10) as u8 + b'0') as char); res.insert(0, ((num % 10) as u8 + b'0') as char);
num /= 10; num /= 10;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -192,6 +214,9 @@ impl ToString for u32 {
res.insert(0, ((num % 8) as u8 + b'0') as char); res.insert(0, ((num % 8) as u8 + b'0') as char);
num /= 8; num /= 8;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -206,12 +231,16 @@ impl ToString for u32 {
let mut num = *self; let mut num = *self;
let mut res = String::new(); let mut res = String::new();
while num != 0 { while num != 0 {
res.insert(0, (tohex(num % 16) + b'0') as char); res.insert(0, tohex(num % 16) as char);
num /= 16; num /= 16;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
} }
impl ToString for u64 { impl ToString for u64 {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let mut num = *self; let mut num = *self;
@ -220,6 +249,9 @@ impl ToString for u64 {
res.insert(0, ((num % 10) as u8 + b'0') as char); res.insert(0, ((num % 10) as u8 + b'0') as char);
num /= 10; num /= 10;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -230,6 +262,9 @@ impl ToString for u64 {
res.insert(0, ((num % 8) as u8 + b'0') as char); res.insert(0, ((num % 8) as u8 + b'0') as char);
num /= 8; num /= 8;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -244,12 +279,16 @@ impl ToString for u64 {
let mut num = *self; let mut num = *self;
let mut res = String::new(); let mut res = String::new();
while num != 0 { while num != 0 {
res.insert(0, (tohex(num % 16) + b'0') as char); res.insert(0, tohex(num % 16) as char);
num /= 16; num /= 16;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
} }
impl ToString for u128 { impl ToString for u128 {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let mut num = *self; let mut num = *self;
@ -258,6 +297,9 @@ impl ToString for u128 {
res.insert(0, ((num % 10) as u8 + b'0') as char); res.insert(0, ((num % 10) as u8 + b'0') as char);
num /= 10; num /= 10;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -268,6 +310,9 @@ impl ToString for u128 {
res.insert(0, ((num % 8) as u8 + b'0') as char); res.insert(0, ((num % 8) as u8 + b'0') as char);
num /= 8; num /= 8;
} }
if res.len() == 0 {
res.insert(0, '0');
}
res res
} }
@ -282,9 +327,60 @@ impl ToString for u128 {
let mut num = *self; let mut num = *self;
let mut res = String::new(); let mut res = String::new();
while num != 0 { while num != 0 {
res.insert(0, (tohex(num % 16) + b'0') as char); res.insert(0, tohex(num % 16) as char);
num /= 16; 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 res
} }
} }

View File

@ -1,11 +1,14 @@
use core::{ use core::{
alloc::Layout, alloc::Layout,
ops::{Index, IndexMut, Range, RangeFull}, ops::{Index, IndexMut, Range, RangeFull},
ptr::{addr_of_mut, null_mut}, ptr::addr_of_mut,
slice, slice,
}; };
use crate::libk::alloc::alloc::{alloc, dealloc}; use crate::libk::{
alloc::alloc::{alloc, dealloc},
core::ptr::PtrOptions,
};
pub struct Vec<T> { pub struct Vec<T> {
pointer: *mut T, pointer: *mut T,
@ -16,15 +19,15 @@ pub struct Vec<T> {
impl<T: Default> Vec<T> { impl<T: Default> Vec<T> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
pointer: null_mut(), pointer: unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() },
length: 0, length: 0,
capacity: 0, capacity: 4,
} }
} }
unsafe fn extend_capacity(&mut self) { unsafe fn extend_capacity(&mut self) {
let newp = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast(); let newp: *mut T = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
self.pointer.copy_to(newp, self.length); self.pointer.kcopy_to(newp, self.length);
dealloc( dealloc(
self.pointer.cast(), self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(), Layout::array::<T>(self.capacity).unwrap(),
@ -34,11 +37,6 @@ impl<T: Default> Vec<T> {
} }
pub fn push(&mut self, item: T) { pub fn push(&mut self, item: T) {
if self.pointer.is_null() {
self.pointer = unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() };
self.capacity = 4;
self.length = 0;
}
if self.capacity == self.length { if self.capacity == self.length {
unsafe { self.extend_capacity() } unsafe { self.extend_capacity() }
} }
@ -54,11 +52,11 @@ impl<T: Default> Vec<T> {
unsafe { unsafe {
if rearlen != 0 { if rearlen != 0 {
let tmp = alloc(Layout::array::<T>(rearlen).unwrap()).cast(); let tmp = alloc(Layout::array::<T>(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).write(item);
self.pointer self.pointer
.offset(index as isize + 1) .offset(index as isize + 1)
.copy_from(tmp, rearlen); .kcopy_from(tmp, rearlen);
} else { } else {
self.pointer.offset(self.length as isize).write(item); self.pointer.offset(self.length as isize).write(item);
} }
@ -73,7 +71,7 @@ impl<T: Default> Vec<T> {
unsafe { unsafe {
self.pointer self.pointer
.offset(self.length as isize) .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; self.length += v.length;
} }
@ -108,8 +106,8 @@ impl<T: Default> Vec<T> {
let mut t: T = T::default(); let mut t: T = T::default();
let pt = addr_of_mut!(t); let pt = addr_of_mut!(t);
unsafe { unsafe {
pt.copy_from(self.pointer.offset(index as isize).cast_const(), 1); pt.kcopy_from(self.pointer.offset(index as isize).cast_const(), 1);
self.pointer.offset(index as isize).copy_from( self.pointer.offset(index as isize).kcopy_from(
self.pointer.offset(index as isize + 1), self.pointer.offset(index as isize + 1),
self.length - index - 1, self.length - index - 1,
); );
@ -172,7 +170,7 @@ impl<T: Default> Clone for Vec<T> {
}; };
unsafe { unsafe {
res.pointer res.pointer
.copy_from(self.pointer.cast_const(), self.length) .kcopy_from(self.pointer.cast_const(), self.length)
}; };
res res
} }
@ -264,7 +262,7 @@ impl<T: Default> Iterator for VecIter<T> {
let res = unsafe { let res = unsafe {
self.pointer self.pointer
.offset(self.index as isize) .offset(self.index as isize)
.copy_to(addr_of_mut!(t), 1); .kcopy_to(addr_of_mut!(t), 1);
Some(t) Some(t)
}; };
self.index += 1; self.index += 1;

View File

@ -0,0 +1 @@
pub mod ptr;

30
src/libk/core/ptr/mod.rs Normal file
View File

@ -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<T> {
unsafe fn kcopy_from(self, src: *const T, count: usize);
unsafe fn kcopy_to(self, des: *const T, count: usize);
}
impl<T> PtrOptions<T> for *mut T {
unsafe fn kcopy_from(self, src: *const T, count: usize) {
memcpy(
transmute(self.cast_const()),
transmute(src),
count * size_of::<T>(),
);
}
unsafe fn kcopy_to(self, des: *const T, count: usize) {
memcpy(
transmute(des),
transmute(self.cast_const()),
count * size_of::<T>(),
);
}
}