?
Solved

Protected Memory Exception

Posted on 2006-12-01
12
Medium Priority
?
303 Views
Last Modified: 2010-04-16
I have an application that is giving me the following exception :
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I think it has something to do with the fact that I am making calls to unmanaged code through interop.  I never had this problem until I started doing the interops through background workers.  I am trying to transverse a directories and files and read one type of file in order to load it into a table in a mysql database.  These files I am trying to read and load into the table are of a custom file type.  It takes the code written in C++ to open and read the files, therefore I have to make the calls through interop.  Because there are so many directories I start off 30 Background workers and continuously start each one with a directory to process.  So I know there are constant hits to the interop and dll that the interop is accessing.  Here is my code...

Here is the method that keeps crashing with the exception:
private DataTable SpreadtoTable()
            {
            int ptr = -1;
            try
            {
                int lrc, lrr;
                int[] cols, wids;
                StringBuilder line = new StringBuilder(81);
                StringBuilder lineatt = new StringBuilder(128);

                DataTable dtSpread = new DataTable();

                ptr = SpreadClass.read_spread(mPath);
                if (ptr == 0 || ptr == -1)
                    return null;

                lrr = SpreadClass.get_LRR(ptr);
                lrc = SpreadClass.get_LRC(ptr);
                cols = new int[lrc];
                wids = new int[lrc];

                SpreadClass.get_col_indexs(ptr, cols, wids);

                for (int k = 1; k <= lrc; k++)
                {
                    SpreadClass.get_column_attr(ptr, "Column Name", cols[k - 1], line, lineatt);
                    if (line.ToString().ToUpper() == "DATE")
                        dtSpread.Columns.Add(line.ToString(), Type.GetType("System.DateTime"));
                    else
                        dtSpread.Columns.Add(line.ToString());
                }

                for (int i = 1; i <= lrr; i++)
                {
                    DataRow dr = dtSpread.NewRow();

                    for (int j = 1; j <= lrc; j++)
                    {
                        SpreadClass.getraw(ptr, i, cols[j - 1], line, lineatt);
                        dr[j - 1] = line.ToString();
                    }

                    dtSpread.Rows.Add(dr);
                }
                SpreadClass.deletedb(ptr);
                return dtSpread;
            }
            catch (Exception ex)
            {
                StreamWriter sw = new StreamWriter(spreadLog, true);
                FileInfo fi = new FileInfo(mPath);
                sw.WriteLine(ex.Message + " = " + fi.DirectoryName + " - Unable to convert Master.Cat to table");
                sw.Close();
                return null;
            }
            finally
            {
                SpreadClass.deletedb(ptr);
            }
}

Here are my DllImports:
            [DllImport("spread.dll")]
            public static extern int read_spread(string      fname);

            [DllImport("spread.dll")]
            public static extern void getraw(int ptr, int row, int col,
                  [MarshalAs(UnmanagedType.LPStr)]StringBuilder str,
                  [MarshalAs(UnmanagedType.LPStr)]StringBuilder stratt);

            [DllImport("spread.dll")]
            public static extern int get_LRC(int file);

            [DllImport("spread.dll")]
            public static extern int get_LRR(int file);

            [DllImport("spread.dll")]
            public static extern void get_column_attr(int ptr, string headatt,
                  int column,
                  [MarshalAs(UnmanagedType.LPStr)]StringBuilder str,
                  [MarshalAs(UnmanagedType.LPStr)]StringBuilder stratt);


Here is the C Code            
/****************************************************************************/
long int read_spread ( fname )
char             *fname;
{
}

/****************************************************************************/
getraw ( dbptr, row, col, str, stratt )
long int    dbptr;
int         row;
int         col;
char        *str;
char        *stratt;
{
}

/****************************************************************************/
get_LRC(fileptr)
long int fileptr;
{
}

/****************************************************************************/
get_LRR(fileptr)
long int fileptr;
{
}

/****************************************************************************/
get_column_attr ( dbptr, colatt, col, str, stratt )
long int    dbptr;
char        *colatt;
int         col;
char        *str;
char        *stratt;
{
}

I know that this is a lot to read and look at, but any advice will be greatly appreciated....

Thanks,
Kendal

0
Comment
Question by:gvector1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
12 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 18058875
Can you show exactly what C# line gives exception?
0
 

Author Comment

by:gvector1
ID: 18068909
It is the SpreadClass.deletedb(ptr).  This is where the memory is where the pointer to the file is disposed of and the memory released.  It has always worked fine until now.  I was kind of thinking that it may have something to do with my threading.  What do you think?????
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18069203
SpreadClass.deletedb(ptr);

This line is executed twice - in try block and in finally block. Remove it from try block.
If this doesn't help, post enough information to understand what happens: you the code you posted it is impossinle to see what happens in deletedb function, how unmanaged functions are called.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:gvector1
ID: 18104395
Could it be possible that the dll that I am using Interop calls to is not thread safe.  Is it possible that that could have any bearing on this.  I took the first deletedb statement out, but the problem still occurs.  I am thinking that if the dll is not thread safe, when multiple threads are making calls at the same time to the dll that this type of problem can occur.  Is this possible??????
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18106845
Yes, this is possible. To test this run the same code in one thread and see whether it happens.
0
 

Author Comment

by:gvector1
ID: 18114825
I origionally did this in one thread.  Never had this problem...but it was taking too long.  This application has to transverse hundreds of thousands of directories and parse one specific file in each directory to load it into a database.  Now here is another question.  How can I create a lock that will work across threads.  Basically so when one thread goes to access the dll method call it will lock until it is done and any other subsequent calls will be blocked until the first call is complete.  It that an acceptable workaround and how would it ideally be done?????
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18115383
You can create static object for synchronization:

static object syncObject = new Object();

Make every call to unmanaged library by the following way:

lock(syncObject)
{
    // unmanaged call
}

Using static synchronization object serializes all calls inside of lock{} block in the whole program.
I don't understand completely your code. Possibly it is enough to protect resources only for every class instance. In this case use non-static synchronization object:
object syncObject = new Object();

Try both versions. First gives better protection, but it is slower. I don't know exactly reading your code, whether you need first or second version.
0
 

Author Comment

by:gvector1
ID: 18115725
My application starts and I start about 30 background workers which work through directories opening specific files that require the dll to read.  Each bg worker opens the file and loads the contents into a database table.  
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 18116594
The criteria is what kind of resources are accessed by function, or unmanaged function. If these resources belong to class instance, it is enough to use protection on instance level. If this is global resource, protection should be done on global (static) level.
0
 

Author Comment

by:gvector1
ID: 18117179
These resources are accessed at an instance level.  Each Background Worker creates an instance of a class that accesses the resource.  So am I correct in saying that if the instance of the class creates a lock on the object, another background worker will not be able to create a lock and access the resource????
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 18120752
This work by the following way. If you make lock on instance level:

lock(syncObject)   // syncObject is non-static
{
    // protected code
}

different threads which try to execute protected code in the same instance, cannot execute it at the same time. Only one thread can enter lock block. If other thread tries to do this, it waits when first thread releases lock, and only after this enters the block. Protected code is always executed only by one thread.

If syncObject is static, only one thread can execute protected code for all class instances.
0
 

Author Comment

by:gvector1
ID: 18229301
Thanks AlexFM,
That lock code helped me out greatly.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question