解决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导致最终调用了一个含有未正确链接的函数。
======== 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 -> <str as metaverse::libk::alloc::string::ToString>::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 -> <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};
#[derive(Clone, Default)]
#[derive(Default)]
pub struct String {
data: Vec<char>,
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 {
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
}
}

View File

@ -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<T> {
pointer: *mut T,
@ -16,15 +19,15 @@ pub struct Vec<T> {
impl<T: Default> Vec<T> {
pub fn new() -> Self {
Self {
pointer: null_mut(),
pointer: unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() },
length: 0,
capacity: 0,
capacity: 4,
}
}
unsafe fn extend_capacity(&mut self) {
let newp = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
self.pointer.copy_to(newp, self.length);
let newp: *mut T = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
self.pointer.kcopy_to(newp, self.length);
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
@ -34,11 +37,6 @@ impl<T: Default> Vec<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 {
unsafe { self.extend_capacity() }
}
@ -54,11 +52,11 @@ impl<T: Default> Vec<T> {
unsafe {
if rearlen != 0 {
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 + 1)
.copy_from(tmp, rearlen);
.kcopy_from(tmp, rearlen);
} else {
self.pointer.offset(self.length as isize).write(item);
}
@ -73,7 +71,7 @@ impl<T: Default> Vec<T> {
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<T: Default> Vec<T> {
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<T: Default> Clone for Vec<T> {
};
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<T: Default> Iterator for VecIter<T> {
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;

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>(),
);
}
}