Last active
August 29, 2015 14:14
-
-
Save pnkfelix/2e2b73092c2fd5b38228 to your computer and use it in GitHub Desktop.
illustrates erroneous deallocate calls both with and without `-O` on Mac OS X
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(lang_items)] | |
#![feature(int_uint)] | |
#![no_std] | |
#![allow(unstable)] | |
#![allow(unused_variables)] | |
#![allow(non_camel_case_types)] | |
#![allow(non_upper_case_globals)] | |
extern crate core; | |
// extern crate alloc; | |
extern crate libc; | |
use core::mem; | |
use core::ptr::{self, PtrExt, Unique}; | |
use core::str::StrExt; | |
use core::slice::SliceExt; | |
use libc::{c_int}; | |
#[inline(never)] | |
fn box_1() -> Box<[i8; 1]> { | |
let v = [1i8]; | |
// Box::new(v) | |
let b : Box<[i8; 1]> = unsafe { | |
let p = allocate(mem::size_of_val(&v), | |
mem::align_of_val(&v)); | |
mem::transmute(p) | |
}; | |
b | |
} | |
#[inline(never)] | |
fn box_2() -> Box<[i8; 2]> { | |
let v = [1i8, 2]; | |
// Box::new(v) | |
let b : Box<[i8; 2]> = unsafe { | |
let p = allocate(mem::size_of_val(&v), | |
mem::align_of_val(&v)); | |
mem::transmute(p) | |
}; | |
b | |
} | |
#[inline(never)] | |
fn box_3() -> Box<[i8; 3]> { | |
let v = [1i8, 2, 3]; | |
// Box::new(v) | |
let b : Box<[i8; 3]> = unsafe { | |
let p = allocate(mem::size_of_val(&v), | |
mem::align_of_val(&v)); | |
mem::transmute(p) | |
}; | |
b | |
} | |
#[inline(never)] | |
fn box_4() -> Box<[i8; 4]> { | |
let v = [1i8, 2, 3, 4]; | |
// Box::new(v) | |
let b : Box<[i8; 4]> = unsafe { | |
let p = allocate(mem::size_of_val(&v), | |
mem::align_of_val(&v)); | |
mem::transmute(p) | |
}; | |
b | |
} | |
pub fn main() { | |
print0("Hello World 1\n\0"); | |
let _: Box<[i8]> = match 2 { | |
1 => box_1(), | |
2 => box_2(), | |
3 => box_3(), | |
_ => box_4(), | |
}; | |
print0("Hello World 2\n\0"); | |
} | |
#[lang = "owned_box"] | |
pub struct Box<T>(Unique<T>); | |
#[lang = "start"] | |
fn lang_start(_main: *const u8, argc: isize, argv: *const *const u8) -> isize { | |
main(); | |
0 | |
} | |
pub const EMPTY: *mut () = 0x1 as *mut (); | |
#[lang="exchange_malloc"] | |
#[inline(never)] | |
unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 { | |
if size == 0 { | |
EMPTY as *mut u8 | |
} else { | |
let ptr = allocate(size, align); | |
if ptr.is_null() { print0("Uh oh\n\0"); loop { } } | |
ptr | |
} | |
} | |
#[lang="exchange_free"] | |
#[inline(never)] | |
unsafe fn exchange_free(ptr: *mut u8, old_size: uint, align: uint) { | |
print_p(" exchange_free ptr %p (no-op)\n\0", ptr); | |
print_us(" exchange_free old_size %ld\n\0", old_size); | |
print_us(" exchange_free align %ld\n\0", align); | |
let low = ¢ral_store[0]; | |
let high = ¢ral_store[offset]; | |
let low : *const u8 = mem::transmute(low); | |
let high : *const u8 = mem::transmute(high); | |
print_p(" exchange_free low %p\n\0", low); | |
print_p(" exchange_free high %p\n\0", high); | |
let low : *mut u8 = mem::transmute(low); | |
let high : *mut u8 = mem::transmute(high); | |
if ptr < low || ptr >= high { | |
print_p("WARNING: called exchange_free on %p \ | |
which is out of range\n\0", ptr); | |
} | |
} | |
#[inline(never)] | |
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 { | |
print_us(" allocate size: %ld\n\0", size); | |
print_us(" allocate align: %ld\n\0", align); | |
let mut p; | |
loop { | |
p = ¢ral_store[offset]; | |
if mem::transmute::<_, usize>(p) % align == 0 { | |
break; | |
} | |
if offset > STORE_SIZE - 1 { | |
let p : *const u8 = ptr::null(); | |
print_p(" allocate returns %p\n\0", p); | |
return mem::transmute(p); | |
} | |
offset += 1; | |
} | |
if offset > STORE_SIZE - size { | |
let p : *const u8 = ptr::null(); | |
print_p(" allocate returns %p\n\0", p); | |
return mem::transmute(p); | |
} | |
offset += size; | |
let p: *const u8 = mem::transmute(p); | |
print_p(" allocate returns %p\n\0", p); | |
return mem::transmute(p); | |
} | |
const STORE_SIZE: usize = 1024; | |
static mut central_store: [u8; STORE_SIZE] = [0; STORE_SIZE]; | |
static mut offset: usize = 0; | |
extern { | |
fn printf(format: *const u8, ...); | |
} | |
fn print0(s: &str) { | |
unsafe { | |
printf(s.as_bytes().as_ptr()); | |
} | |
} | |
fn print_p<T>(s: &str, p: *const T) { | |
unsafe { | |
printf(s.as_bytes().as_ptr(), p); | |
} | |
} | |
fn print_us(s: &str, us: usize) { | |
unsafe { | |
printf(s.as_bytes().as_ptr(), us); | |
} | |
} | |
#[lang="eh_personality"] | |
extern fn rust_eh_personality( | |
version: c_int, | |
actions: uw::_Unwind_Action, | |
exception_class: uw::_Unwind_Exception_Class, | |
ue_header: *mut uw::_Unwind_Exception, | |
context: *mut uw::_Unwind_Context) | |
-> uw::_Unwind_Reason_Code | |
{ | |
loop { } | |
} | |
#[lang = "panic_fmt"] | |
pub extern fn rust_begin_unwind( | |
msg: fmt::Arguments, | |
file: &'static str, | |
line: usize) | |
-> ! | |
{ | |
loop { } | |
} | |
#[lang = "stack_exhausted"] | |
extern fn stack_exhausted() { | |
loop { } | |
} | |
mod uw { | |
use libc; | |
#[repr(C)] | |
pub enum _Unwind_Reason_Code { | |
_URC_NO_REASON = 0, | |
_URC_FOREIGN_EXCEPTION_CAUGHT = 1, | |
_URC_FATAL_PHASE2_ERROR = 2, | |
_URC_FATAL_PHASE1_ERROR = 3, | |
_URC_NORMAL_STOP = 4, | |
_URC_END_OF_STACK = 5, | |
_URC_HANDLER_FOUND = 6, | |
_URC_INSTALL_CONTEXT = 7, | |
_URC_CONTINUE_UNWIND = 8, | |
_URC_FAILURE = 9, // used only by ARM EABI | |
} | |
pub enum _Unwind_Context {} | |
#[repr(C)] | |
pub struct _Unwind_Exception { | |
pub exception_class: _Unwind_Exception_Class, | |
pub exception_cleanup: _Unwind_Exception_Cleanup_Fn, | |
pub private: [_Unwind_Word; unwinder_private_data_size], | |
} | |
pub type _Unwind_Exception_Class = u64; | |
#[repr(C)] | |
pub enum _Unwind_Action { | |
_UA_SEARCH_PHASE = 1, | |
_UA_CLEANUP_PHASE = 2, | |
_UA_HANDLER_FRAME = 4, | |
_UA_FORCE_UNWIND = 8, | |
_UA_END_OF_STACK = 16, | |
} | |
pub type _Unwind_Exception_Cleanup_Fn = | |
extern "C" fn(unwind_code: _Unwind_Reason_Code, | |
exception: *mut _Unwind_Exception); | |
pub type _Unwind_Word = libc::uintptr_t; | |
#[cfg(target_arch = "x86")] | |
pub const unwinder_private_data_size: uint = 5; | |
#[cfg(target_arch = "x86_64")] | |
pub const unwinder_private_data_size: uint = 6; | |
#[cfg(all(target_arch = "arm", not(target_os = "ios")))] | |
pub const unwinder_private_data_size: uint = 20; | |
#[cfg(all(target_arch = "arm", target_os = "ios"))] | |
pub const unwinder_private_data_size: uint = 5; | |
#[cfg(target_arch = "aarch64")] | |
pub const unwinder_private_data_size: uint = 2; | |
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))] | |
pub const unwinder_private_data_size: uint = 2; | |
} | |
mod fmt { | |
pub struct Arguments; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% rustc -O /tmp/coerce_match_calls4.rs && ./coerce_match_calls4 | |
Hello World 1 | |
allocate size: 2 | |
allocate align: 1 | |
allocate returns 0x10319b1d0 | |
exchange_free ptr 0x10319b1d0 (no-op) | |
exchange_free old_size 2 | |
exchange_free align 1 | |
exchange_free low 0x10319b1d0 | |
exchange_free high 0x10319b1d2 | |
exchange_free ptr 0x80000000903 (no-op) | |
exchange_free old_size 4 | |
exchange_free align 1 | |
exchange_free low 0x10319b1d0 | |
exchange_free high 0x10319b1d2 | |
WARNING: called exchange_free on 0x80000000903 which is out of range | |
exchange_free ptr 0xe0000000f03 (no-op) | |
exchange_free old_size 3 | |
exchange_free align 1 | |
exchange_free low 0x10319b1d0 | |
exchange_free high 0x10319b1d2 | |
WARNING: called exchange_free on 0xe0000000f03 which is out of range | |
exchange_free ptr 0x140000001503 (no-op) | |
exchange_free old_size 1 | |
exchange_free align 1 | |
exchange_free low 0x10319b1d0 | |
exchange_free high 0x10319b1d2 | |
WARNING: called exchange_free on 0x140000001503 which is out of range | |
Hello World 2 | |
% rustc /tmp/coerce_match_calls4.rs && ./coerce_match_calls4 | |
Hello World 1 | |
allocate size: 2 | |
allocate align: 1 | |
allocate returns 0x1025c2220 | |
exchange_free ptr 0x1025c2220 (no-op) | |
exchange_free old_size 2 | |
exchange_free align 1 | |
exchange_free low 0x1025c2220 | |
exchange_free high 0x1025c2222 | |
exchange_free ptr 0x1 (no-op) | |
exchange_free old_size 1 | |
exchange_free align 1 | |
exchange_free low 0x1025c2220 | |
exchange_free high 0x1025c2222 | |
WARNING: called exchange_free on 0x1 which is out of range | |
Hello World 2 | |
% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment