Discussion:
[Mono-dev] "safe" way about Marshal.UnsafeAddrOfPinnedArrayElement
GaoXianchao
2006-04-18 04:27:33 UTC
Permalink
hi all,
I'm wrapping epoll api on linux.
To pass address of managed struct array to unmanaged code, I use
Marshal.UnsafeAddrOfPinnedArrayElement . But the method is "unsafe".
Is there a "safe" way to do what the Marshal.UnsafeAd
Jonathan Pryor
2006-04-18 11:48:11 UTC
Permalink
Post by GaoXianchao
hi all,
I'm wrapping epoll api on linux.
To pass address of managed struct array to unmanaged code, I use
Marshal.UnsafeAddrOfPinnedArrayElement . But the method is "unsafe".
Is there a "safe" way to do what the Marshal.UnsafeAddrOfPinnedArrayElement do?
It's "unsafe" because you need to be careful. :-)

An alternative is to use *real* unsafe code, e.g.

FooStruct[] array = ...;
unsafe {
fixed (FooStruct* pArray = array) {
FooStruct* element = &pArray [index];
}
}

I'm not entirely sure what your problem is though. "Unsafe" code (like
the above `unsafe' block) just means that you're possibly executing
without a net, which could result in memory corruption and abortion of
the process. :-)

Marshal.UnsafeAddrOfPinnedArrayElement isn't even in an unsafe C#
context, it just has "Unsafe" in the name.

Here's a hint of truth: ANY time you do a P/Invoke, you're potentially
doing something unsafe. :-)

(Especially considering that you're invoking external code which could
really do anything, such as overwrite the entire GC heap, which would
cause the process an ugly death in the future...)

However, I'm not sure why you need
Marshal.UnsafeAddrOfPinnedArrayElement in the first place.
epoll_wait(2) takes a `struct epoll_event' array parameter, so unless
you wanted to only send a subset of your array, the default marshaling
rules which convert a managed array to an array pointer should be fine.

- Jon
Kornél Pál
2006-04-18 12:13:36 UTC
Permalink
Hi,

Unsafe code usually means code that uses pointers. But that unsafe code has
to use the fixed statement when accessing objects that can be moved. fixed
statement pins the object so that GC will not move it within the block of
fixed statement. (As far as I know Mono still uses non-moving GC but that
will change in the future and MS.NET uses moving GC.)

Marshal.UnsafeAddrOfPinnedArrayElement is unsafe in addition to pointer
operations because it assumes that the array is already pinned so it won't
(an in fact can't as it has no scope) pin the object so the GC can move it
that can result in invalidation of the returned pointer so has to be used
carefully. (When the array is moved by the GC you can overwrite some other
object that can have unpredictable results.)

Marshal.UnsafeAddrOfPinnedArrayElement is intended to be used with a pinned
GCHandle. (Or alternatively on an array that is already pinned using fixed
statement but in that case you have a pointer to an array element so you
probably don't need this method.)

If you have a non-pinned array you should use fixed statement instead as
Jonathan explained it.

So Marshal.UnsafeAddrOfPinnedArrayElement is even more unsafe than unsafe
code when used on a non-pinned array.

Kornél

----- Original Message -----
From: "Jonathan Pryor" <***@vt.edu>
To: "GaoXianchao" <***@gmail.com>
Cc: <mono-devel-***@lists.ximian.com>
Sent: Tuesday, April 18, 2006 1:48 PM
Subject: Re: [Mono-dev] "safe" way about
Marshal.UnsafeAddrOfPinnedArrayElement
Post by Jonathan Pryor
Post by GaoXianchao
hi all,
I'm wrapping epoll api on linux.
To pass address of managed struct array to unmanaged code, I use
Marshal.UnsafeAddrOfPinnedArrayElement . But the method is "unsafe".
Is there a "safe" way to do what the
Marshal.UnsafeAddrOfPinnedArrayElement do?
It's "unsafe" because you need to be careful. :-)
An alternative is to use *real* unsafe code, e.g.
FooStruct[] array = ...;
unsafe {
fixed (FooStruct* pArray = array) {
FooStruct* element = &pArray [index];
}
}
I'm not entirely sure what your problem is though. "Unsafe" code (like
the above `unsafe' block) just means that you're possibly executing
without a net, which could result in memory corruption and abortion of
the process. :-)
Marshal.UnsafeAddrOfPinnedArrayElement isn't even in an unsafe C#
context, it just has "Unsafe" in the name.
Here's a hint of truth: ANY time you do a P/Invoke, you're potentially
doing something unsafe. :-)
(Especially considering that you're invoking external code which could
really do anything, such as overwrite the entire GC heap, which would
cause the process an ugly death in the future...)
However, I'm not sure why you need
Marshal.UnsafeAddrOfPinnedArrayElement in the first place.
epoll_wait(2) takes a `struct epoll_event' array parameter, so unless
you wanted to only send a subset of your array, the default marshaling
rules which convert a managed array to an array pointer should be fine.
- Jon
_______________________________________________
Mono-devel-list mailing list
http://lists.ximian.com/mailman/listinfo/mono-devel-list
Sebastien Pouliot
2006-04-18 12:38:37 UTC
Permalink
Hello,
Post by GaoXianchao
hi all,
I'm wrapping epoll api on linux.
To pass address of managed struct array to unmanaged code, I use
Marshal.UnsafeAddrOfPinnedArrayElement . But the method is "unsafe".
Is there a "safe" way to do what the Marshal.UnsafeAddrOfPinnedArrayElement do?
Safe and unsafe are used for different meanings between languages (e.g.
C#) and the framework base class library.

In this case, like many times it's used in the FX BCL, the Unsafe prefix
means that special security requirements for this method makes it
dangerous to use with non fully-trusted code (see MSDN documentation for
more details).

So unless you are using "mono --security" to activate the (partial and
unsupported) security manager this *doesn't* affect you at all (as all
your code is *always* executed under FullTrust).
--
Sebastien Pouliot <***@ximian.com>
Blog: http://pages.infinit.net/ctech/
Andreas Nahr
2006-04-18 19:02:19 UTC
Permalink
I tested some of my Winforms Apps on Mono 1.1.15 running on WinXP x64.
Most of the real-world apps didn't start, but some small sample ones did.
Here are some notes about Problems with the ones that did:

Toolwindow:
Wrong clipping region/ Window size calculation? See screenshot

Propertygrid:
* Dividing line at wrong position -> should be at 50% of width of control.
* Readonly Elements not grayed out -> Gray out
* Readonly Elements show designers (if designers are used -> crash) -> Don't
display designers for readonly elements
* Category Names not determined correctly if inherited -> Use inherited
CategoryName Attributes
* Description default is currently: "Title<crlf>The long important
Description" -> should be ""
* Default: All Entries expanded -> Should be: All entries NOT expanded
* Setting values does not work
* ToolbarVisible/HelpVisible ignored sometimes -> See screenshot

DirectorySearcher:
Crashes with any selection

Happy hacking!
Andreas
Peter Dennis Bartok
2006-04-18 19:08:42 UTC
Permalink
Andreas,

Thanks for the testing. I'd be great if you could log bugs for these, that
way we don't loose track of them. Also, if you could provide links where to
get the sample apps you used, that would help in reproducing the problems.

What were the problems with the real-world apps?

Cheers,
Peter

-----Original Message-----
From: "Andreas Nahr" <***@A-SoftTech.com>
To: <mono-devel-***@lists.ximian.com>
Date: 18 April, 2006 13:04
Subject: [Mono-dev] Feedback for Windows Forms in 1.1.15
Post by Andreas Nahr
I tested some of my Winforms Apps on Mono 1.1.15 running on WinXP x64.
Most of the real-world apps didn't start, but some small sample ones did.
Wrong clipping region/ Window size calculation? See screenshot
* Dividing line at wrong position -> should be at 50% of width of control.
* Readonly Elements not grayed out -> Gray out
* Readonly Elements show designers (if designers are used -> crash) ->
Don't
display designers for readonly elements
* Category Names not determined correctly if inherited -> Use inherited
CategoryName Attributes
* Description default is currently: "Title<crlf>The long important
Description" -> should be ""
* Default: All Entries expanded -> Should be: All entries NOT expanded
* Setting values does not work
* ToolbarVisible/HelpVisible ignored sometimes -> See screenshot
Crashes with any selection
Happy hacking!
Andreas
Andreas Nahr
2006-04-19 16:52:27 UTC
Permalink
Hi Peter,

if I find some time I will log the bugs. The sample apps used are not
currently available, but I think the problems described are easily
reproduceable even from the screenshots and are mostly not bugs but just
missing or incorrectly implemented features.

I also found out what the problems with most of the bigger apps is: They all
use an ImageList and throw exceptions. I'll add the CallStack:

Unhandled Exception: System.Reflection.TargetInvocationException: Exception
has been thrown by the target of an invocation. --->
System.ArgumentException: Invalid Parameter. A null reference or invalid
value was found.
in <0x00084> System.Drawing.GDIPlus:CheckStatus (Status status)
in <0x001e0> System.Drawing.Image:InitFromStream (System.IO.Stream stream)
in <0x0001c> System.Drawing.Bitmap:.ctor (System.IO.Stream stream, Boolean
useIcm)
in <0x0000f> System.Drawing.Bitmap:.ctor (System.IO.Stream stream)
in (wrapper remoting-invoke-with-check) System.Drawing.Bitmap:.ctor
(System.IO.Stream)
in <0x004f9> System.Windows.Forms.ImageListStreamer:.ctor
(System.Runtime.Serialization.SerializationInfo info, StreamingContext
context)
in <0x00000> <unknown method>
in (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke
(object,object[])
in <0x0008d> System.Reflection.MonoCMethod:Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[]
parameters, System.Globalization.CultureInfo culture)--- End of inner
exception stack trace ---
in <0x0010e> System.Reflection.MonoCMethod:Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[]
parameters, System.Globalization.CultureInfo culture)
in <0x0001a> System.Reflection.MethodBase:Invoke (System.Object obj,
System.Object[] parameters)
in <0x001db> System.Runtime.Serialization.ObjectRecord:LoadData
(System.Runtime.Serialization.ObjectManager manager, ISurrogateSelector
selector, StreamingContext context)
in <0x00110> System.Runtime.Serialization.ObjectManager:DoFixups ()
in <0x00042>
System.Runtime.Serialization.Formatters.Binary.ObjectReader:ReadNextObject
(System.IO.BinaryReader reader)
in <0x000a3>
System.Runtime.Serialization.Formatters.Binary.ObjectReader:ReadObjectGraph
(System.IO.BinaryReader reader, Boolean readHeaders, System.Object result,
System.Runtime.Remoting.Messaging.Header[] headers)
in <0x0011f>
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter:NoCheckDeserialize
(System.IO.Stream serializationStream,
System.Runtime.Remoting.Messaging.HeaderHandler handler)
in <0x0000f>
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter:Deserialize
(System.IO.Stream serializationStream)
in <0x00032> System.Resources.ResourceReader:ReadNonPredefinedValue
(System.Type exp_type)
in <0x0031e> System.Resources.ResourceReader:ReadValueVer1 (System.Type
type)
in <0x00163> System.Resources.ResourceReader:ResourceValue (Int32 index)
in <0x00028> System.Resources.ResourceReader+ResourceEnumerator:get_Value ()
in <0x0007e> System.Resources.ResourceSet:ReadResources ()
in <0x00049> System.Resources.ResourceSet:GetObject (System.String name,
Boolean ignoreCase)
in <0x0007a> System.Resources.ResourceManager:GetObject (System.String name,
System.Globalization.CultureInfo culture)
in <0x00010> System.Resources.ResourceManager:GetObject (System.String name)
in <0x00b77> FileCenter.FileCenter:InitializeComponent ()
in (wrapper remoting-invoke-with-check)
FileCenter.FileCenter:InitializeComponent ()
in <0x00061> FileCenter.FileCenter:.ctor ()
in (wrapper remoting-invoke-with-check) FileCenter.FileCenter:.ctor ()
in <0x00018> FileCenter.FileCenter:Main ()

Also to make things a little bit easier I wrote a small application that
lets you start Mono WinForms Apps without using the Commandline ;)
Currently the tool only works on MS.Net (seems as if Mono Winforms does not
support Drag-And-Drop yet).

Cheers,
Andreas
Post by Peter Dennis Bartok
Thanks for the testing. I'd be great if you could log bugs for these, that
way we don't loose track of them. Also, if you could provide links where to
get the sample apps you used, that would help in reproducing the problems.
What were the problems with the real-world apps?
Cheers,
Peter
-----Original Message-----
Date: 18 April, 2006 13:04
Subject: [Mono-dev] Feedback for Windows Forms in 1.1.15
Post by Andreas Nahr
I tested some of my Winforms Apps on Mono 1.1.15 running on WinXP x64.
Most of the real-world apps didn't start, but some small sample ones did.
Wrong clipping region/ Window size calculation? See screenshot
* Dividing line at wrong position -> should be at 50% of width of control.
* Readonly Elements not grayed out -> Gray out
* Readonly Elements show designers (if designers are used -> crash) ->
Don't
display designers for readonly elements
* Category Names not determined correctly if inherited -> Use inherited
CategoryName Attributes
* Description default is currently: "Title<crlf>The long important
Description" -> should be ""
* Default: All Entries expanded -> Should be: All entries NOT expanded
* Setting values does not work
* ToolbarVisible/HelpVisible ignored sometimes -> See screenshot
Crashes with any selection
Happy hacking!
Andreas
Peter Dennis Bartok
2006-04-19 17:05:24 UTC
Permalink
Also to make things a little bit easier I wrote a small application that
lets you start Mono WinForms Apps without using the Commandline ;)
Currently the tool only works on MS.Net (seems as if Mono Winforms does not
support Drag-And-Drop yet).
No, we do support DnD on both X11 and Win32.

I'll look into it and see what it does.

As for the imagelist issues, we've got a bug logged for that already.

Cheers,
Peter
Loading...