What is unsafe in this code?
I am learning about managed and unmanaged code in CLR. So I wrote this example with C-style pointers in C#:
unsafe static void Main(string[] args)
{
int x;
int* y;
y = &x;
*y = 50;
Console.WriteLine(*y);
Console.WriteLine(((int)y).ToString());
}
So I am wondering what really is unsafe in IL code that I got from the code above?
.assembly extern mscorlib
{}
.assembly UnsafePointers
{}
.module UnsafePointers.exe
.class private auto ansi beforefieldinit UnsafePointers.Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 34 (0x22)
.locals init (int32 x,
int32* y)
IL_0001: ldloca x
IL_0003: conv.u
IL_0004: stloc y
IL_0005: ldloc y
IL_0006: ldc.i4 50
IL_0008: stind.i4
IL_0009: ldloc y
IL_000a: ldind.i4
IL_000b: call void [mscorlib]System.Cons开发者_JAVA百科ole::WriteLine(int32)
IL_0010: nop
IL_0011: ldloca y
IL_0012: conv.i4
IL_0016: call instance string [mscorlib]System.Int32::ToString()
IL_001b: call void [mscorlib]System.Console::WriteLine(string)
IL_0021: ret
}
}
Does CLR manages this code? And what can go wrong with a code above?
What makes this code unsafe is the use of the 'ldind.i4' statement. This loads a signed 4-byte integer from a memory address. Any memory address can be given, allowing you to read from any memory address in the current process. This is considered unsafe and unverifiable. For instance, you could use this to look inside other appdomains, which is not allowed.
It's called unsafe, partly because it is not managed.
You can easily create c++ style memory leaks, there are no boundary checks, and other problems...
A nice article about unsafe code, also lists a few risks:
Using Unsafe Code in C#
Unsafe may not mean dangerous, but there is one thing that is important in unsafe code: it is unverifiable. This can mean several things, such as not checking the bounds of an array. In your simple example. there isn't that much dangerous or scary about it. It's pretty straight forward.
In can be unsafe because it also gets around most of the security mechanisms in the .NET Framework; which is why unsafe code requires Full Trust anyway.
Unsafe != Unmanaged. Unsafe just means it can manipulate pointers.
In general, the unsafe
keyword allows you direct access to memory and therefore bypasses all verification and safety checks by the CLR.
Here's a good article on the use and impact of unsafe
code:
http://blogs.msdn.com/b/sebby1234/archive/2006/04/05/565090.aspx
By default, Microsoft’s C# and Visual Basic.NET compilers produce “safe” code. Safe code is code that is verifiably safe. However, using C#’s unsafe keyword or using other languages (such as C++ with Managed Extensions or IL Assembly language), you can produce code that cannot be verifiably safe. That is, the code might, in fact, be safe, but the verification is unable to prove it.
an administrator can elect to turn verification off (using the ".NET Management" Microsoft Management Console Snap-In). With verification off, the JIT compiler will compile unverifiable IL into native CPU instructions; however, the administrator is taking full responsibility for the code's behavior.
精彩评论