diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) Henning Thielemann 2018
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+test-build:
+	runhaskell Setup configure --user -f-debug
+	runhaskell Setup build
+	runhaskell Setup haddock
+
+	runhaskell Setup configure --user -fdebug
+	runhaskell Setup build
+
+%.html:	%.md
+	pandoc $< --output=$@
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+The overall idea of the package is to make programming mistakes
+let low-level programs fail reproducibly.
+
+What the routines do:
+
+ *  After allocation fill the memory with the hex string 0xDEADF00D.
+    This allows to check whether the caller
+    properly initialises allocated buffers.
+
+ *  Allocate some memory before and after the actual buffer
+    and fill it with 0xABADCAFE.
+    On deallocation it is checked that this pattern is still intact.
+    If not, abort with an error.
+    This allows to check for range violations.
+
+ *  Before deallocation fill the memory with 0xDEADBEEF.
+    This helps to detect when the program reads memory after its deallocation.
+
+ *  The `create` routine additionally makes a copy of the initialized buffer.
+    The finalizer compares the contents of the buffer and its copy.
+    This way it can detect if an immutable array was altered after its creation.
+
+
+Range violations might alternatively be detected by range checking techniques.
+Allocation problems might be solved using Regions.
+The provided functions might overlook range violations
+but they help detecting bugs
+when you have not full control over the code that processes memory content,
+e.g. when calling external routines via FFI.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#! /usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/frontend/debug/Foreign/Marshal/Array/Guarded.hs b/frontend/debug/Foreign/Marshal/Array/Guarded.hs
new file mode 100644
--- /dev/null
+++ b/frontend/debug/Foreign/Marshal/Array/Guarded.hs
@@ -0,0 +1,6 @@
+module Foreign.Marshal.Array.Guarded (
+   Array.create,
+   Array.alloca,
+   ) where
+
+import qualified Foreign.Marshal.Array.Guarded.Debug as Array
diff --git a/frontend/plain/Foreign/Marshal/Array/Guarded.hs b/frontend/plain/Foreign/Marshal/Array/Guarded.hs
new file mode 100644
--- /dev/null
+++ b/frontend/plain/Foreign/Marshal/Array/Guarded.hs
@@ -0,0 +1,6 @@
+module Foreign.Marshal.Array.Guarded (
+   Array.create,
+   Array.alloca,
+   ) where
+
+import qualified Foreign.Marshal.Array.Guarded.Plain as Array
diff --git a/guarded-allocation.cabal b/guarded-allocation.cabal
new file mode 100644
--- /dev/null
+++ b/guarded-allocation.cabal
@@ -0,0 +1,67 @@
+Name:             guarded-allocation
+Version:          0.0
+License:          BSD3
+License-File:     LICENSE
+Author:           Henning Thielemann <haskell@henning-thielemann.de>
+Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>
+Homepage:         http://hub.darcs.net/thielema/guarded-allocation/
+Category:         Debug
+Synopsis:         Memory allocation with added stress tests and integrity checks
+Description:
+  Provide adaptions of @mallocForeignPtrArray@ and @allocaArray@
+  that add stress tests and integrity checks.
+  .
+  There are three modules:
+  .
+  * @Guarded.Plain@: exports the original allocation routines
+  .
+  * @Guarded.Debug@: exports allocation routines that add stress and checks
+  .
+  * @Guarded@: exports either @Guarded.Plain@ or @Guarded.Debug@
+    depending on the Cabal @debug@ flag.
+  .
+  It is intended that you always import the @Guarded@ module in user code
+  and install a package version with enabled debug flag
+  to a custom package database for debugging.
+  If you compile your user program you can choose production or debugging mode
+  by choosing the default or the custom debugging package database,
+  respectively.
+  .
+  This package is inspired by the famous Amiga debug tool MungWall.
+  The Linux counterpart is Electric Fence.
+
+Tested-With:      GHC==7.4.2, GHC==7.8.4, GHC==8.4.3
+Cabal-Version:    >=1.6
+Build-Type:       Simple
+Extra-Source-Files:
+  Makefile
+  README.md
+
+Source-Repository this
+  Tag:         0.1
+  Type:        darcs
+  Location:    http://hub.darcs.net/thielema/guarded-allocation/
+
+Source-Repository head
+  Type:        darcs
+  Location:    http://hub.darcs.net/thielema/guarded-allocation/
+
+Flag debug
+  Description: Add stress tests and integrity checks to allocations
+  Default:     False
+  Manual:      True
+
+Library
+  Build-Depends:
+    base >=4.5 && <5
+
+  GHC-Options:      -Wall
+  Hs-Source-Dirs:   src
+  If flag(debug)
+    Hs-Source-Dirs: frontend/debug
+  Else
+    Hs-Source-Dirs: frontend/plain
+  Exposed-Modules:
+    Foreign.Marshal.Array.Guarded
+    Foreign.Marshal.Array.Guarded.Plain
+    Foreign.Marshal.Array.Guarded.Debug
diff --git a/src/Foreign/Marshal/Array/Guarded/Debug.hs b/src/Foreign/Marshal/Array/Guarded/Debug.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Array/Guarded/Debug.hs
@@ -0,0 +1,100 @@
+module Foreign.Marshal.Array.Guarded.Debug (
+   create,
+   alloca,
+   ) where
+
+import qualified Foreign.Marshal.Array.Guarded.Plain as Plain
+
+import Foreign.Marshal.Array
+         (mallocArray, allocaArray, pokeArray, copyArray, advancePtr)
+import Foreign.Marshal.Alloc (free)
+import Foreign.Storable (Storable, peekByteOff, sizeOf)
+import Foreign.Concurrent (newForeignPtr)
+import Foreign.ForeignPtr (ForeignPtr)
+import Foreign.Ptr (Ptr, castPtr)
+
+import Control.Monad (when)
+
+import Data.Foldable (for_)
+import Data.Word (Word8)
+
+
+{- |
+Array creation with additional immutability check, electrical fence
+and pollution of uncleaned memory.
+
+The function checks that the array is not altered anymore after creation.
+-}
+create :: (Storable a) => Int -> (Ptr a -> IO b) -> IO (ForeignPtr a, b)
+create = flip asTypeOf Plain.create $ \size f -> do
+   let border = 64
+   let fullSize = size + 2*border
+   ptrApre <- mallocArray fullSize
+   ptrsA@(_ptrApre, ptrA, _ptrApost) <- fillAll border size ptrApre
+   result <- f ptrA
+   checkAll border ptrsA
+   ptrB <- mallocArray size
+   copyArray ptrB ptrA size
+   fmap (flip (,) result) $ newForeignPtr ptrA $ do
+      for_ (take (arraySize ptrA size) [0..]) $ \i -> do
+         a <- peekByteOff ptrA i
+         b <- peekByteOff ptrB i
+         when (a/=(b::Word8)) $
+            error $ "immutable array was altered at byte position " ++ show i
+      trash fullSize ptrApre
+      free ptrApre
+      free ptrB
+
+
+alloca :: (Storable a) => Int -> (Ptr a -> IO b) -> IO b
+alloca = flip asTypeOf Plain.alloca $ \size f -> do
+   let border = 64
+   let fullSize = size + 2*border
+   allocaArray fullSize $ \ptrPre -> do
+      ptrs@(_ptrPre, ptr, _ptrPost) <- fillAll border size ptrPre
+      result <- f ptr
+      checkAll border ptrs
+      trash fullSize ptrPre
+      return result
+
+
+fillAll :: (Storable a) => Int -> Int -> Ptr a -> IO (Ptr a, Ptr a, Ptr a)
+fillAll border size ptrPre = do
+   let ptr = advancePtr ptrPre border
+   let ptrPost = advancePtr ptr size
+   fill ptrPre border [0xAB,0xAD,0xCA,0xFE]
+   fill ptr size [0xDE,0xAD,0xF0,0x0D]
+   fill ptrPost border [0xAB,0xAD,0xCA,0xFE]
+   return (ptrPre, ptr, ptrPost)
+
+checkAll :: (Storable a) => Int -> (Ptr a, Ptr a, Ptr a) -> IO ()
+checkAll border (ptrPre, _ptr, ptrPost) = do
+   check "leading"  ptrPre  border [0xAB,0xAD,0xCA,0xFE]
+   check "trailing" ptrPost border [0xAB,0xAD,0xCA,0xFE]
+
+trash :: (Storable a) => Int -> Ptr a -> IO ()
+trash fullSize ptrPre = fill ptrPre fullSize [0xDE,0xAD,0xBE,0xEF]
+
+
+{-# INLINE fill #-}
+fill :: (Storable a) => Ptr a -> Int -> [Word8] -> IO ()
+fill ptr n bytes =
+   pokeArray (castPtr ptr) $ take (arraySize ptr n) $ cycle bytes
+
+{-# INLINE check #-}
+check :: (Storable a) => String -> Ptr a -> Int -> [Word8] -> IO ()
+check name ptr n bytes =
+   for_ (take (arraySize ptr n) $ zip [0..] $ cycle bytes) $ \(i,b) -> do
+      a <- peekByteOff ptr i
+      when (a/=(b::Word8)) $
+         error $ "damaged " ++ name ++ " fence at position " ++ show i
+
+arraySize :: (Storable a) => Ptr a -> Int -> Int
+arraySize ptr n = arraySizeAux ptr n $ error "arraySize: undefined element"
+
+{- |
+Correct size computation should also respect padding caused by alignment.
+However, mallocArray uses this simple arithmetic.
+-}
+arraySizeAux :: (Storable a) => Ptr a -> Int -> a -> Int
+arraySizeAux _ n a = n * sizeOf a
diff --git a/src/Foreign/Marshal/Array/Guarded/Plain.hs b/src/Foreign/Marshal/Array/Guarded/Plain.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Array/Guarded/Plain.hs
@@ -0,0 +1,20 @@
+module Foreign.Marshal.Array.Guarded.Plain (
+   create,
+   alloca,
+   ) where
+
+import Foreign.Marshal.Array (allocaArray)
+import Foreign.Storable (Storable)
+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrArray)
+import Foreign.Ptr (Ptr)
+
+import Control.Applicative ((<$>))
+
+
+create :: (Storable a) => Int -> (Ptr a -> IO b) -> IO (ForeignPtr a, b)
+create size f = do
+   fptr <- mallocForeignPtrArray size
+   (,) fptr <$> withForeignPtr fptr f
+
+alloca :: (Storable a) => Int -> (Ptr a -> IO b) -> IO b
+alloca = allocaArray
