C ++中的字符串逻辑错误

时间:2014-12-05 08:37:51

标签: c++ string multithreading gdb

我正在编写一个程序,它将使用位操作来评估竞争条件,然后还将使用信号量锁定/解锁来消除这些竞争条件。

我用“./raceTest 5 6 3 6 unlock”运行该程序。所有输出都很好。但现在它与解锁arg崩溃了。

当我尝试使用这些args编译它时,我的程序崩溃了:./ rasTest 5 6 3 6 lock(或任何带有“lock”的args)

这就是输出带有“lock”命令。它现在崩溃了...即使它没有崩溃“解锁”并正确显示一切。

./raceTest 5 6 3 6 lock
lock
nBuffers is 5
mWorkers is 6
sleepMin is 3
sleepMax is 6
randarray 4 
randarray 3
randarray 6
randarray 3
randarray 4
randarray 4
Segmentation fault

我曾尝试使用gdb,当我运行该程序时,我从gdb

中收到此错误
Starting program: /mnt_nfs/home3/ugrad3/ariley/Desktop/cs361/hw5/raceTest
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
[Thread debugging using libthread_db enabled]
terminate called after throwing an instance of 'std::logic_error'
what():  basic_string::_S_construct NULL not valid

Program received signal SIGABRT, Aborted.
0x0000003156430265 in raise () from /lib64/libc.so.6

有人可以告诉我这意味着什么吗?它早先工作了。但现在它不起作用,我没有做任何事情......

// raceTest program
#include <string> 
#include <iostream> 
#include <stdlib.h> 
#include <time.h> 
#include <pthread.h>
#include <sys/sem.h> 
#include <sys/types.h> 
#include <sys/stat.h>

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
union semun
{
int val;                // value for SETVAL
struct semid_ds *buf;   // buffer for IPC_STAT, IPC_SET
unsigned short *array;  // array for GETALL, SETALL 
struct seminfo *_buf;   // buffer for IPC_INFO
};
#endif 

static int sem_id = 0; 
static int sem_semvalue();
static void del_semvalue();
static int semaphore_p();
static int semaphore_v();

using namespace std; 

// struct for the threads 
typedef struct thread
{
int nbuffers; 
int ID; 
double sleepTime; 
int semID; 
int mutexID; 
int *buffer; 
int nReadErrors; 
} Thread_data; 

void *worker(void *targ) 
{ 
cout << "In worker function" << endl; 
// cast back to a struct variable to use 
Thread_data *data = (Thread_data*) targ; 

int errors=0; 

for (int i=0 ; i < data->nbuffers; i++) 
{
    // READ the value of buffers at that thread's ID, starting from current ID 
    int read = data->buffer[data->ID]; 
    usleep(data->sleepTime); 
    // see if the value changed after sleeping 
    int secondRead = data->buffer[data->ID]; 
    if (secondRead != read)
    {           
        cout << " Worker " << data->buffer[data->ID] << " reported change from " << read << " to       secondRead " << secondRead;
        cout << " in buffer " << i << endl; 
        errors ++; 
    }

    read = (read + data->ID) % (data->nbuffers); // next read

    usleep(data->sleepTime); 
    secondRead = data->buffer[read]; 
    if (secondRead != read)
    {           
        cout << " Worker " << data->buffer[data->ID] << "reported change from " << read << " to secondRead " << secondRead;
        cout << " in buffer " << i << endl; 
        errors ++; 
    }

    // write operations to do 
    read = (read + data->ID) % (data->nbuffers);
    usleep(data->sleepTime);
    // add to the buffer array, or the WRITE
    data->buffer[read] = secondRead + ( 1 << (data->ID - 1) );
}
data->nReadErrors = errors;  // update 4. 
pthread_exit(NULL);
}


int main (int argc, char * argv[])
{
int i; // handle all command line arguements
int nBuffers = 0; 
int mWorkers = 0; 
int sleepMin = 0; 
int sleepMax = 0; 
srand(time(NULL));
key_t key = IPC_PRIVATE; 
int rErrors = 0; 
int wErrors = 0; 

// parse command line arguments 
// USAGE: raceTest nBuffers nWorkers sleepMin sleepMax [ randSeed ] [ -lock | -nolock ]
for (i=1 ; i<argc-1 ; i++)
{
    // Check input 
    string s = argv[i]; 
    int num = atoi( s.c_str() ); // UPDATE 5 
    //cout << "argv at " << i << " is " << num << endl; 

    if (num == 0)
    {
        cout << "USAGE: raceTest nBuffers nWorkers sleepMin sleepMax [ randSeed ] [ -lock | -    nolock ]" << endl; 
        cout << "Exiting..." << endl; 
        exit(-1);
    }
}
string s = argv[i++]; 
cout << s << endl; 

// set variables to command line arguments
// nBuffers has restrictions 
nBuffers = atoi(argv[1]);
if ( nBuffers <= 2 || nBuffers >= 32)
{
    cout << "nBuffers is the wrong size. Exiting" << endl; 
    exit (-1); 

    if (nBuffers != 3 || nBuffers != 7 || nBuffers != 11 || nBuffers != 17 || nBuffers !=5
        || nBuffers != 13 || nBuffers != 19 || nBuffers != 23 || nBuffers != 31 || nBuffers !=   29)
    {
            cout << "nBuffers must be prime. Exiting" << endl; 
            exit (-2); 
    }
}

mWorkers = atoi(argv[2]);  cout << "nBuffers is " << nBuffers << endl;
sleepMin = atoi(argv[3]);  cout << "mWorkers is " << mWorkers << endl;
sleepMax = atoi(argv[4]);  cout << "sleepMin is " << sleepMin << endl;  
cout << "sleepMax is " << sleepMax << endl;

int buffers[nBuffers]; 
double randWorkers[mWorkers]; 

// initialize the arrays 
for (int i=0 ; i<nBuffers ; i++)
    buffers[i] = 0; 

for (int i=0 ; i<mWorkers ; i++)
{
    // generate random number between sleepMin and sleepMax 
    int temp = rand() % (sleepMax - sleepMin + 1) + sleepMin; 
    randWorkers[i] = temp; 
    cout << "randarray " << randWorkers[i] << endl;
}

// sort the numbers in decreasing order 
for (int i=0 ; i<mWorkers ; i++)
{
    for (int j=0 ; j< mWorkers ; j++)
    {
        if (randWorkers[i] < randWorkers[j])
        {
            cout << "here" << endl;
            // simple sorting 
            double temp = randWorkers[i];
            randWorkers[i] = randWorkers[j]; 
            randWorkers[j] = temp;  
            cout << randWorkers[i] << " "; 
        }
    }
}
// other sorting method 
//sort (randWorkers, sizeof(randWorkers), greater<double>);

// create an array of M structs and populate each with values needed 
// for the threads 
Thread_data threadVals[mWorkers]; 

for (int i=0 ; i<mWorkers ; i++)
{
    threadVals[i].nbuffers = nBuffers; 
    threadVals[i].ID = i+1; 
    threadVals[i].sleepTime = randWorkers[i]; 
    threadVals[i].semID = -1; 
    threadVals[i].mutexID = -1; 
    threadVals[i].nReadErrors = 0; 
    threadVals[i].buffer = buffers;
}

// create an array of M (threads) where each runs the 
// worker() function 
pthread_t tid[nBuffers];

for (int i=0 ; i<mWorkers ; i++)
{
    // don't do any locking 
    if ( strcmp (s.c_str(), "nolock") == 0)
    {
        // pass a pointer to one of the structs 
        int value = pthread_create (&tid[i], NULL, worker, &threadVals[i]); 
        if (value != 0)
        {
            perror ("thread creation failed");  
            exit(-3); 
        }
        else 
            cout << "successful creation for " << tid[nBuffers] << endl; 
    }

    // use semaphores for the locking 
    else if (strcmp(s.c_str() , "lock") == 0)
    {
        /*cout << "B-----" << endl; 
        int sem_id = semget(key, 1, IPC_CREAT|0666); 
        if (sem_id < 0)
        {
            perror ( "Cannot create sem_id"); 
            exit(-5); 
        }
        cout << "A-----" << endl; */
        ;
    }
}

// wait for all of the threads to finish 
for (int j=0 ; j<mWorkers ; j++)
{
    pthread_join(tid[j], NULL); 
}

for (int i=0 ; i< nBuffers ; i++)
{
    int size = 2^ mWorkers - 1; 
    if (buffers[i] == size)
        break;  // this particular index is the same 

    cout << "Bad bits for buffer[" << i <<"] = " ; 
    int diff = size ^ buffers[i]; 
    for (int j=0 ; j <mWorkers  ; j++) 
    {
        // perform a binary OR and then binary AND
        int position = (diff) & (1<<j); 
        //cout << buffer[position] << W" ";
        if (position)
            cout << j << " " ; 
        wErrors++; 
    }
    cout << endl; 
}

// figure the total number of read errors 
for (int i=0 ; i<mWorkers ; i++)
    rErrors = rErrors + threadVals[i].nReadErrors; 

cout << "Total Errors: " << "read errors: " << rErrors << " write errors " << wErrors << endl; 
return 0;
}

EDIT :: 这就是我做bt时所得到的,恐怕我真的不明白这些东西是什么意思......

Program received signal SIGSEGV, Segmentation fault.
0x000000315643471a in ____strtoll_l_internal () from /lib64/libc.so.6
(gdb) bt
#0  0x000000315643471a in ____strtoll_l_internal () from /lib64/libc.so.6
#1  0x0000003156431bd2 in atoi () from /lib64/libc.so.6
#2  0x00000000004010a5 in main (argc=1, argv=0x7fffffffded8) at raceTest.cpp:171
(gdb) up
#1  0x0000003156431bd2 in atoi () from /lib64/libc.so.6
(gdb)
#2  0x00000000004010a5 in main (argc=1, argv=0x7fffffffded8) at raceTest.cpp:171
171             nBuffers = atoi(argv[1]);
(gdb)
Initial frame selected; you cannot go up.
(gdb) print nBuffers
$1 = 0

第二次编辑:无论我是刚刚进​​行碰撞还是使用信号量。我做的唯一改变是将数组参数从nBuffers更改为nWorkers,然后测试rand的输出以查看它是否产生了未定义的行为。

[ariley@bert hw5]$ ./raceTest 5 6 3 6 lock
5
6  
3
6
5beforenBuffers is 5
mWorkers is 6
sleepMin is 3
sleepMax is 6
value of temp4
randarray 4
value of temp6
randarray 6
value of temp3
randarray 3
value of temp5
randarray 5
value of temp4
randarray 4
value of temp6
randarray 6
successful creation for 6300416
In worker function
successful creation for 6300416
successful creation for 47840834492736
Segmentation fault

2 个答案:

答案 0 :(得分:2)

pthread_t tid[nBuffers];

应该是

pthread_t tid[mWorkers];

除非参数集是'nolock'(不是'unlock'),否则不会初始化tid []数组,因此使用无效的参数调用pthread_join(tid [i],NULL)。

标记。

答案 1 :(得分:0)

  

有人可以告诉我这意味着什么吗?

这意味着你做了(相当于)这个:

char *cp = NULL;
std::string s(cp);  // throws logic_error