简体   繁体   中英

Threads C++, Access Violation reading location x error

Platform : Windows 7
I'm developing a project for known text cipher attack in which;

  • Main process creates n child processes
  • Child processes decrypt an encrypted string, key subspace is partitioned according to number of child processes
  • Communication between child processes are by a static variable

for(int i = 0; i<info.totalNumberOfChildren; i++)
{       
  startChild( &info.childInfoList[i]);
  //_beginthread(startChild, 0, &info.childInfoList[i]);        
}

Above code works fine since:

  • First child starts execution, the key is set as a number such as 8 for testing purposes which is within the first child's partition, so first child finds the key, reports and sets true the killSwitch.
  • All the other children that are created are closed even before checking the first key as the killSwitch is true.

When I however do this :

for(int i = 0; i<info.totalNumberOfChildren; i++)
{

    //startChild( &info.childInfoList[i]);
    _beginthread(startChild, 0, &info.childInfoList[i]);

}

I get an access violation error. What could possibly be my source of error ?

Edit: I will try to share as relevant code as I can

startChild does the following:

void startChild( void* pParams)
{
    ChildInfo *ci = (ChildInfo*)pParams;
    // cout<<"buraya geldi"<<endl;
    ChildProcess cp(*ci);
    // write to log
    cp.completeNextJob();
}

childInfo holds the following : // header file

class ChildInfo
{
public:

    ChildInfo();
    ChildInfo(char * encrypted, char * original, static bool killSwitch, int totalNumOfChildren, int idNum, int orjLen);
    void getNextJob();
    bool keyIsFound();
    Des des;
    void printTest();
    bool stopExecution;
    bool allIsChecked;
    char * encyptedString;
    char * originalString;
    int id;
    int orjStrLen;

private:

    int lastJobCompleted;
    int totalNumberOfChildren;
    int jobDistBits;

};

completeNextJob() does the following :

void ChildProcess::completeNextJob()
{
cout<<"Child Id : "<<info.id<<endl;
// cout<<"Trying : "<<info.encyptedString<<endl; // here I got an error


char * newtrial = info.encyptedString;
char * cand = info.des.Decrypt(newtrial); // here I also get an error if I comment out

/*
cout<<"Resultant : "<<cand<<endl;
cout<<"Comparing with : "<<info.originalString<<endl;
*/

bool match = true;
for(int i = 0; i<info.orjStrLen; i++)
{
    if(!(cand[i] == info.originalString[i]))
        match = false;
}

if(match)
{
    cout<<"It has been acknowledged "<<endl;
    info.stopExecution = true;
    return;
}
else
{
    if(!info.keyIsFound())
    {
        if(!info.allIsChecked)
        {
            info.getNextJob();
            completeNextJob();
        }
        else
        {

        }
    }
    else
    {

    }
}

}

decrypt() method does the following :

char * Des::Decrypt(char *Text1)
{
  int i,a1,j,nB,m,iB,k,K,B[8],n,t,d,round;
  char *Text=new char[1000];
  unsigned char ch;
  strcpy(Text,Text1); // this is where I get the error
  i=strlen(Text);
keygen();
int mc=0;
  for(iB=0,nB=0,m=0;m<(strlen(Text)/8);m++) //Repeat for TextLenth/8 times.
  {
 for(iB=0,i=0;i<8;i++,nB++)
  {
     ch=Text[nB];
     n=(int)ch;//(int)Text[nB];
     for(K=7;n>=1;K--)
     {
      B[K]=n%2;  //Converting 8-Bytes to 64-bit Binary Format
      n/=2;
     } for(;K>=0;K--) B[K]=0;
   for(K=0;K<8;K++,iB++) total[iB]=B[K]; //Now `total' contains the 64-Bit binary format of 8-Bytes
  }
IP(); //Performing initial permutation on `total[64]'
for(i=0;i<64;i++) total[i]=ip[i]; //Store values of ip[64] into total[64]

for(i=0;i<32;i++) left[i]=total[i]; //        +--> left[32]
                    // total[64]--|
for(;i<64;i++) right[i-32]=total[i];//            +--> right[32]
  for(round=1;round<=16;round++)
  {
Expansion(); //Performing expansion on `right[32]' to get  `expansion[48]'
xor_oneD(round);
substitution();//Perform substitution on xor1[48] to get sub[32]
permutation(); //Performing Permutation on sub[32] to get p[32]
xor_two(); //Performing XOR operation on left[32],p[32] to get xor2[32]
for(i=0;i<32;i++) left[i]=right[i]; //Dumping right[32] into left[32]
for(i=0;i<32;i++) right[i]=xor2[i]; //Dumping xor2[32] into right[32]
 } //rounds end here
for(i=0;i<32;i++) temp[i]=right[i]; // Dumping   -->[ swap32bit ]
for(;i<64;i++) temp[i]=left[i-32];  //    left[32],right[32] into temp[64]

inverse(); //Inversing the bits of temp[64] to get inv[8][8]
/* Obtaining the Cypher-Text into final[1000]*/
       k=128;   d=0;
    for(i=0;i<8;i++)
    {
      for(j=0;j<8;j++)
      {
        d=d+inv[i][j]*k;
        k=k/2;
      }
       final[mc++]=(char)d;
       k=128;   d=0;
    }
  } //for loop ends here
  final[mc]='\0';
  char *final1=new char[1000];
  for(i=0,j=strlen(Text);i<strlen(Text);i++,j++)
    final1[i]=final[j]; final1[i]='\0';
  return(final);
}

Debugger is your best friend, try to use it and check step by step what could cause this access violation. I think that info.encyptedString is not initialized correctly and pointing to not allocated memory, but I cant be sure because you didn't show this part of code. And of course you must protect your shared resources ( info ) using some synchronization objects like critical section or mutex or semaphore.

I don't know, the basic issue seems pretty straightforward to me. You have multiple threads executing simultaneously, which access the same information via *pParams, which presumably is of type ChildInfo since that's what you cast it to. That info must be getting accessed elsewhere in the program, perhaps in the main thread. This is corrupting something, which may or may not have to do with Text1 or info.id, these errors can often be 'non-local' and hard to debug for this reason. So start mutex-protecting the entire thread (within your initial loop), and then zero in on the critical sections by trial and error, ie mutex-protect as small a region of code as you can get away with without producing errors.

Windows is trying to tell you why your program crashed. Please use a debugger to see what Windows is talking about. Location X is important: it should tell you whether your program is dereferencing NULL, overflowing a buffer, or doing something else. The call stack at the time of the crash is also very important.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM