Pergunta

trying to debug a modified code to be using unsafe generates an error i dont know if my code is correct with the astrics (so please check if i put those correctly) though there is another issue apart from that... with compiler options in asp.net as opposed to Windows apps, there's no sutible place to check/uncheck the option to using unsafe

and as far as i could get to info about that envolves dealing with the Web.Config "manually"

so i was doing that , added a code to Web.Config, there are two versions of users suggesting to put code within configuration section or within the same scope of debug=true ...

so i put it in both(not at same time , but tried both (:

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
 <system.codedom>
   <compilers>
     <compiler language="C#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   </compilers>
  </system.codedom>
  <connectionStrings>....my secret connection here...
   then rest of configs..
     .....




    struct IO_COUNTERS
    {
        public ulong ReadOperationCount;
        public ulong WriteOperationCount;
        public ulong OtherOperationCount;
        public ulong ReadTransferCount;
        public ulong WriteTransferCount;
        public ulong OtherTransferCount;
    }
    [DllImport("kernel32.dll")]
    unsafe static extern bool GetProcessIoCounters(IntPtr* ProcessHandle, out IO_COUNTERS* IoCounters);


    private struct PROCESS_MEMORY_COUNTERS
    {
        public uint cb;
        public uint PageFaultCount;
        public uint PeakWorkingSetSize;
        public uint WorkingSetSize;
        public uint QuotaPeakPagedPoolUsage;
        public uint QuotaPagedPoolUsage;
        public uint QuotaPeakNonPagedPoolUsage;
        public uint QuotaNonPagedPoolUsage;
        public uint PagefileUsage;
        public uint PeakPagefileUsage;
    }
    [StructLayout(LayoutKind.Sequential, Size = 40)]
    [DllImport("psapi.dll", SetLastError = true)]
    unsafe static extern bool GetProcessMemoryInfo(IntPtr* hProcess, out PROCESS_MEMORY_COUNTERS* Memcounters, int size);

this is the calss that implements native pinvok codes

(at the beginning i was trying to test native vs managed / .net approach ) but before even trying the pinvoke vs .net i dived strait to check on performance btween pinvoke *unsafe vs .net

so this part is still in "safe mode" should it be also treated with the astrics ?

static class Nat
    {
        public static class IO
        {
            public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
                GetProcessIoCounters(System.Diagnostics.Process.GetCurrentProcess().Handle, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }
        public static class Mem
        {
            public static Dictionary<string, uint> GetAllMem(Process procToRtrivMem)
            {

                PROCESS_MEMORY_COUNTERS MemCounters;
                Dictionary<string, uint> retCountMemDict = new Dictionary<string, uint>();
                GetProcessMemoryInfo(System.Diagnostics.Process.GetCurrentProcess().Handle, out MemCounters, Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS))); //MemCounters.cb);
                retCountMemDict.Add("cb", MemCounters.cb);
                retCountMemDict.Add("PageFaultCount", MemCounters.PageFaultCount);
                retCountMemDict.Add("PeakWorkingSetSize", MemCounters.PeakWorkingSetSize);
                retCountMemDict.Add("WorkingSetSize", MemCounters.WorkingSetSize);
                retCountMemDict.Add("QuotaPeakPagedPoolUsage", MemCounters.QuotaPeakPagedPoolUsage);
                retCountMemDict.Add("QuotaPagedPoolUsage", MemCounters.QuotaPagedPoolUsage);

                retCountMemDict.Add("QuotaPeakNonPagedPoolUsage", MemCounters.QuotaPeakNonPagedPoolUsage);
                retCountMemDict.Add("QuotaNonPagedPoolUsage", MemCounters.QuotaNonPagedPoolUsage);
                retCountMemDict.Add("PagefileUsage", MemCounters.PagefileUsage);
                retCountMemDict.Add("PeakPagefileUsage", MemCounters.PeakPagefileUsage);

                return retCountMemDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }

    }

sorry for that, but the update is i missed the part of : compiler option

compilerOptions="/unsafe" // <<-- you can add this to the compiler config line.

though still . my problems only started then cause there is not only one error :

Unsafe code may only appear if compiling with /unsafe 

but errors all over the place !

first one for instance :

            public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();

            --->>   GetProcessIoCounters(System.Diagnostics.Process.GetCurrentProcess().Handle, out counters);


                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);

the error is for that line calling GetProcesIoCounters()

Error 3 Argument 1: cannot convert from 'System.IntPtr' to 'System.IntPtr*' g:\RobDevI5-Raid-0\Documents\Visual Studio 2010\WebSites\WebSite2\App_Code\CsExtensions.cs 416 42 g:...\WebSite2\

UPDAT - Code That seem to work though i could not verify it is using unsafe properly

signeture with unsafe

    [DllImport("psapi.dll", SetLastError = true)]
    unsafe static extern bool GetProcessMemoryInfo(IntPtr* hProcess, out PROCESS_MEMORY_COUNTERS Memcounters, int size);

code with my "unsafe"

        public static class IO
        {
            public static unsafe Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
                IntPtr* Hw = (IntPtr*)System.Diagnostics.Process.GetCurrentProcess().Handle;
                GetProcessIoCounters(Hw, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        }
Foi útil?

Solução 2

Ok you need to change a few things, shown below

using System.Collections.Generic;
using System.Runtime.InteropServices;
using System;
using System.Diagnostics;
static class Nat
{
    [StructLayout(LayoutKind.Sequential]
    struct IO_COUNTERS
    {
        public ulong ReadOperationCount;
        public ulong WriteOperationCount;
        public ulong OtherOperationCount;
        public ulong ReadTransferCount;
        public ulong WriteTransferCount;
        public ulong OtherTransferCount;
    }
    [DllImport("kernel32.dll")]
    unsafe static extern bool GetProcessIoCounters(IntPtr ProcessHandle, out IO_COUNTERS IoCounters);

    [StructLayout(LayoutKind.Sequential, Size = 40)]
    private struct PROCESS_MEMORY_COUNTERS
    {
        public uint cb;
        public uint PageFaultCount;
        public uint PeakWorkingSetSize;
        public uint WorkingSetSize;
        public uint QuotaPeakPagedPoolUsage;
        public uint QuotaPagedPoolUsage;
        public uint QuotaPeakNonPagedPoolUsage;
        public uint QuotaNonPagedPoolUsage;
        public uint PagefileUsage;
        public uint PeakPagefileUsage;
    }

    [DllImport("psapi.dll", SetLastError = true)]
    unsafe static extern bool GetProcessMemoryInfo(IntPtr* hProcess, out PROCESS_MEMORY_COUNTERS* Memcounters, int size);

    public static class IO
    {
        unsafe public static Dictionary<string, ulong> GetALLIO(Process procToRtrivIO)
        {
            IO_COUNTERS counters;
            Dictionary<string, ulong> retCountIoDict = new Dictionary<string, ulong>();
            IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

            GetProcessIoCounters(ptr, out counters);
            retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
            retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
            retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
            retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
            retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
            retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
            return retCountIoDict;
            //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
            //    " Mb of data.";

        }
    }
    public static class Mem
    {
        unsafe public static Dictionary<string, uint> GetAllMem(Process procToRtrivMem)
        {

            PROCESS_MEMORY_COUNTERS* MemCounters;
            Dictionary<string, uint> retCountMemDict = new Dictionary<string, uint>();
            IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

            GetProcessMemoryInfo(&ptr, out MemCounters, Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS))); //MemCounters.cb);
            retCountMemDict.Add("cb", MemCounters->cb);
            retCountMemDict.Add("PageFaultCount", MemCounters->PageFaultCount);
            retCountMemDict.Add("PeakWorkingSetSize", MemCounters->PeakWorkingSetSize);
            retCountMemDict.Add("WorkingSetSize", MemCounters->WorkingSetSize);
            retCountMemDict.Add("QuotaPeakPagedPoolUsage", MemCounters->QuotaPeakPagedPoolUsage);
            retCountMemDict.Add("QuotaPagedPoolUsage", MemCounters->QuotaPagedPoolUsage);

            retCountMemDict.Add("QuotaPeakNonPagedPoolUsage", MemCounters->QuotaPeakNonPagedPoolUsage);
            retCountMemDict.Add("QuotaNonPagedPoolUsage", MemCounters->QuotaNonPagedPoolUsage);
            retCountMemDict.Add("PagefileUsage", MemCounters->PagefileUsage);
            retCountMemDict.Add("PeakPagefileUsage", MemCounters->PeakPagefileUsage);

            return retCountMemDict;
            //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
            //    " Mb of data.";

        }
    }

}

Outras dicas

Necromancing.
The accepted answer contains code that doesn't work.
Here's the corrected version that does work:

namespace MemoryInfo
{


    class Program
    {

        static void Main(string[] args)
        {
            System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
            Nat.Mem.GetAllMem(proc);
            Nat.IO.GetALLIO(proc);
        }
    }



    // http://www.pinvoke.net/default.aspx/psapi.getprocessmemoryinfo
    static class Nat
    {


        // [DllImport("kernel32.dll")]
        // public static extern IntPtr GetCurrentProcess();

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        private struct IO_COUNTERS
        {
            public ulong ReadOperationCount;
            public ulong WriteOperationCount;
            public ulong OtherOperationCount;
            public ulong ReadTransferCount;
            public ulong WriteTransferCount;
            public ulong OtherTransferCount;
        }


        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Size = 40)]
        private struct PROCESS_MEMORY_COUNTERS
        {
            public uint cb; // The size of the structure, in bytes (DWORD).
            public uint PageFaultCount; // The number of page faults (DWORD).
            public uint PeakWorkingSetSize; // The peak working set size, in bytes (SIZE_T).
            public uint WorkingSetSize; // The current working set size, in bytes (SIZE_T).
            public uint QuotaPeakPagedPoolUsage; // The peak paged pool usage, in bytes (SIZE_T).
            public uint QuotaPagedPoolUsage; // The current paged pool usage, in bytes (SIZE_T).
            public uint QuotaPeakNonPagedPoolUsage; // The peak nonpaged pool usage, in bytes (SIZE_T).
            public uint QuotaNonPagedPoolUsage; // The current nonpaged pool usage, in bytes (SIZE_T).
            public uint PagefileUsage; // The Commit Charge value in bytes for this process (SIZE_T). Commit Charge is the total amount of memory that the memory manager has committed for a running process.
            public uint PeakPagefileUsage; // The peak value in bytes of the Commit Charge during the lifetime of this process (SIZE_T).
        }


        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private unsafe static extern bool GetProcessIoCounters(System.IntPtr ProcessHandle, out IO_COUNTERS IoCounters);

        [System.Runtime.InteropServices.DllImport("psapi.dll", SetLastError = true)]
        private unsafe static extern bool GetProcessMemoryInfo(System.IntPtr hProcess, out PROCESS_MEMORY_COUNTERS counters, uint size);


        public static class IO
        {
            unsafe public static System.Collections.Generic.Dictionary<string, ulong> GetALLIO(System.Diagnostics.Process procToRtrivIO)
            {
                IO_COUNTERS counters;
                System.Collections.Generic.Dictionary<string, ulong> retCountIoDict = 
                    new System.Collections.Generic.Dictionary<string, ulong>();
                System.IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;

                GetProcessIoCounters(ptr, out counters);
                retCountIoDict.Add("ReadOperationCount", counters.ReadOperationCount);
                retCountIoDict.Add("WriteOperationCount", counters.WriteOperationCount);
                retCountIoDict.Add("OtherOperationCount", counters.OtherOperationCount);
                retCountIoDict.Add("ReadTransferCount", counters.ReadTransferCount);
                retCountIoDict.Add("WriteTransferCount", counters.WriteTransferCount);
                retCountIoDict.Add("OtherTransferCount", counters.OtherTransferCount);
                return retCountIoDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";

            }
        } // End Class IO 


        public static class Mem
        {
            unsafe public static System.Collections.Generic.Dictionary<string, uint> GetAllMem(System.Diagnostics.Process procToRtrivMem)
            {
                PROCESS_MEMORY_COUNTERS MemCounters;
                System.Collections.Generic.Dictionary<string, uint> retCountMemDict = 
                    new System.Collections.Generic.Dictionary<string, uint>();
                System.IntPtr ptr = System.Diagnostics.Process.GetCurrentProcess().Handle;
                uint nativeStructSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS));


                GetProcessMemoryInfo(ptr, out MemCounters, nativeStructSize); //MemCounters.cb);
                retCountMemDict.Add("cb", MemCounters.cb);
                retCountMemDict.Add("PageFaultCount", MemCounters.PageFaultCount);
                retCountMemDict.Add("PeakWorkingSetSize", MemCounters.PeakWorkingSetSize);
                retCountMemDict.Add("WorkingSetSize", MemCounters.WorkingSetSize);
                retCountMemDict.Add("QuotaPeakPagedPoolUsage", MemCounters.QuotaPeakPagedPoolUsage);
                retCountMemDict.Add("QuotaPagedPoolUsage", MemCounters.QuotaPagedPoolUsage);

                retCountMemDict.Add("QuotaPeakNonPagedPoolUsage", MemCounters.QuotaPeakNonPagedPoolUsage);
                retCountMemDict.Add("QuotaNonPagedPoolUsage", MemCounters.QuotaNonPagedPoolUsage);
                retCountMemDict.Add("PagefileUsage", MemCounters.PagefileUsage);
                retCountMemDict.Add("PeakPagefileUsage", MemCounters.PeakPagefileUsage);

                return retCountMemDict;
                //return  "This process has read " + ((counters.ReadTransferCount/1024)/1024).ToString("N0") +
                //    " Mb of data.";
            }


        } // End Class Mem

    }




}

I think your web config line is missing the compilerOptions="/unsafe+" part

e.g.

        <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" compilerOptions="/unsafe+" warningLevel="4" />
    </compilers>

from

It sounds like you need to understand what the asterisk represents. In C#, as in other C-like languages, it denotes a pointer type. For example:

int *

...represents a "pointer to an int". That is, the value of this variable indicates a memory location that contains an int. C# and other .NET languages implement something called type-safety which means that it is difficult to misinterpret values in memory (for example, try to read a string at a memory location that actually contains an int) and this is broadly-speaking a useful thing. However, sometimes, when you're interacting with native code, it is useful to be able to deal in terms of pointers. This subverts the type-safety mechanism and therefore your code must be marked unsafe and you need to compile with the /unsafe switch as already noted.

You seem to suggest that you had an either/or decision between p/invoke and using unsafe code. In my experience this seldom arises because the 2 techniques exist to solve different problems. P/invoke allows you to interact with native code in a way that normally doesn't require you to use unsafe code, but in truth it depends on the nature of the native code you're interacting with.

When you ask whether your "safe mode" code "should it be also treated with the astrics?" I hope my explanation shows you that you don't treat code with asterisks but you declare variables as needed on a case-by-case basis.

In addition your p/invoke declaration for GetProcessIoCounters looks wrong. You seldom see a parameter of type IntPtr *. Check out http://pinvoke.net to look up the correct declaration.

To clear up some more terminology, code can be managed or unmanaged. C# code is always managed. Unmanaged code would be written in one of many languages, such as C, C++, etc. C# code, while always managed, can be type-safe (the default) or you can mark blocks of C# code as unsafe, which allows you to use pointer types.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top