Shared memory value printf strange value though i don't modify it

Viewed 17

i have a process master that launch 2 different type of children... users e nodes. I put in shared memory a default set of information when they are created and i want to print in loop with a pause of 1 second. Initially it works well and print the correct status of every children...but at some time the value of shared memory nodes change like it is reading form a memory that doesn't have permission. for exmaple it start with the pid:1234 and after a certain time it become: -123214322342 but no one touch the memory and if i delete that part that change other value but in the same area it doesn't work too. So my question is that probabli i fail to manipulate correctly the memory but i can't find the problem neither with debug. If i missed something i would put immediatly but the full code would be too much. The file .h are only declaretaion of function and variable and the resumePrint...print the value of shared memory...attach signal handle signals but for a minimun example it doen't need.

master.c

#include "config.h"
#include "master_manager.h"


int* nodeTrList;
int main(int argc, char const *argv[])
{
    nodeTrList = malloc(SO_NODES_NUM * sizeof(struct Transaction));
    initSemaphore(SM_WRITE_MASTERBOOK);
    initSemaphore(SM_TRANSACTION_COMPLETE );
    initSemaphore(SM_WRITE_USER);
    initSemaphore(SM_KEY_SIZE_MASTERBOOK);
    initSemaphore(SM_WRITE_NODE);
    initMasterBook();
    freeMasterBook();
    initMasterBook();
    userList = initSharedMemory(SH_KEY_USER,SH_USERS_LIST_SIZE);
    nodeList = initSharedMemory(SH_KEY_NODE,SH_NODES_LIST_SIZE);

    int queueID = msgget(KEY_QUEUE, IPC_CREAT | 0600);
    setQueueId(queueID);
    attach_signals();

    alarm(SO_SIM_SEC);

    struct termios attributes;

    tcgetattr(STDIN_FILENO, &saved);
    atexit(restore);

    tcgetattr(STDIN_FILENO, &attributes);
    attributes.c_lflag &= ~ ECHO;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &attributes);


    char *argsUser[3] = {USER_NAME};
    char *argsNode[3] = {NODE_NAME};
    char id[5];
    for (int i = 0; i < SO_NODES_NUM; i++)
    {
        int pid = fork();
        switch (pid){
            case 0:
                
                sprintf(id,"%d",i);
                argsNode[1] = id;
                argsNode[2] = NULL;
                execvp(NODE_NAME, argsNode);
                exit(EXIT_FAILURE);
                break;
            case -1:
                printf("Error in main:  fork failed");
                break;
            default:
                printf("\nmaster: launch node %d (pid %d)\n",i,pid);
                nodeTrList[i] = pid;
                nodeList[i].id = i;
                nodeList[i].pid = pid;
                nodeList[i].amount = 0;
                nodeList[i].status = 1;
                nodeList[i].trWaiting = 0;
                nodeList[i].trProcessed = 0;
                break;
        }
    }
    for (int i = 0; i < SO_USERS_NUM; i++)
        {
            int pid = fork();
            switch (pid){
                case 0:
                    sprintf(id,"%d",i);
                    argsUser[1] = id;
                    argsUser[2] = NULL;
                    execvp(USER_NAME, argsUser);
                    exit(EXIT_FAILURE);
                    break;
                case -1:
                    printf("Error in main:  fork failed");
                    break;
                default:
                    printf("\nmaster: launch user %d (pid %d)\n",i,pid);
                    userList[i].budgetAccount = SO_BUDGET_INIT;
                    userList[i].budgetActual = SO_BUDGET_INIT;
                    userList[i].id = i;
                    userList[i].income = 0;
                    userList[i].outcome = 0;
                    userList[i].ntr = 0;
                    userList[i].status = 1;
                    userList[i].pid = pid;
                    break;
            }
        }


    pid_t pidnow;
    int num_bytes;


    while (1)
    {
        resumePrint();
        //printf("\n allora:%d  %d  %d ",nodeList[0].pid,nodeList[1].pid,nodeList[2].pid);sleep(1);
        if (user_done+node_done >= SO_USERS_NUM+SO_NODES_NUM) {
            printMasterBook();
            //resumePrint();
            break;
        }

          if (user_done == SO_USERS_NUM)
        {
            
            for (int i = 0; i < SO_NODES_NUM; i++)
            {
                kill(nodeTrList[i], 5);
                sleep(1);
                kill(nodeTrList[i], 15);
                kill(nodeTrList[i], 9);
               
            }
        }

        pidnow= waitpid(-1, NULL, WNOHANG);
        int found = 0;
        if(pidnow > 0){
            for (int i = 0; i < SO_USERS_NUM; i++)
            {
                int check = getSharedMemoryID(SH_KEY_USER,SH_USERS_LIST_SIZE);
                if(check < 0) return 0;
                if (pidnow == userList[i].pid)
                            {
                                //printf("\nTerminato user: done:%d pid:%d\n", user_done, pidnow);
                                ++user_done;
                                found = 1;
                                break;
                            }
                
                
            }
            if(found == 0){
                for (int j = 0; j < SO_NODES_NUM; j++)
                    {
                        int check = getSharedMemoryID(SH_KEY_USER,SH_USERS_LIST_SIZE);
                        if(check < 0) return 0;
                        if (pidnow == nodeList[j].pid)
                            {
                              //printf("\nTerminato node: done:%d pid:%d\n", node_done, pidnow);
                              ++node_done;
                                break;
                                    }
                                
                            }
            }

           
        }
        
    }
    endMaster("NORMALLY TERMINATED");
    return 0;
}

user.c:

#include "user_manager.h"
int main(int argc, char const *argv[])
{
    ID = atoi(argv[1]);

    initMasterBook(SH_KEY_MASTERBOOK);
   
    int queueID = msgget(KEY_QUEUE, IPC_CREAT | 0600);
    setQueueId(queueID);

    userList = initSharedMemory(SH_KEY_USER,SH_USERS_LIST_SIZE);
    nodeList = initSharedMemory(SH_KEY_NODE,SH_NODES_LIST_SIZE);

    attach_signals();
    srand(getpid());

    int finish = 0,freeTP = 0;

    while (finish < SO_RETRY)
    {
        readMasterBook();
        
        if(makeTransaction() == -1) ++finish;
        
        int delay = rand() % SO_MAX_TRANS_GEN_NSEC / 1000000000 + SO_MIN_TRANS_GEN_NSEC / 1000000000;
        sleep(delay);
    }
    userList[ID].status = 0;
    
    return 0;
}

node.c

#include "node_manager.h"

int main(int argc, char const *argv[])
{
    struct Block block;

    ID = atoi(argv[1]);

    userList = initSharedMemory(SH_KEY_USER,SH_USERS_LIST_SIZE);
    nodeList = initSharedMemory(SH_KEY_NODE,SH_NODES_LIST_SIZE);
    attach_signals();

    if (!initTransactionPool())
    {
        printf("\nError in initTransaction\n");
        exit(EXIT_FAILURE);
    }

    int q_id = msgget(KEY_QUEUE, IPC_CREAT | 0600);
    setQueueId(q_id);

    initMasterBook();

    while (1)
    {
        
        waitTransactions(q_id);
        if (sizeTransactionPool() > SO_BLOCK_SIZE - 1)
        {
            block = createBlock();
             int delay = rand() % SO_MIN_TRANS_PROC_NSEC / 1000000000 + SO_MAX_TRANS_PROC_NSEC / 1000000000;
            sleep(delay);
            if (addBlock(block) > -1)
            {
                for (int i = 0; i < SO_BLOCK_SIZE - 1; i++)
                {
                    removeTransaction(transaction_pool[0]);
                    nodeList[ID].trWaiting-=1;
                    nodeList[ID].trProcessed+=1;
                }
            }
           
        }
    }
    nodeList[ID].status = 0;
    return 0;
}

user_manager.c:

#include "user_manager.h"



int queueID;
struct User* userList;
struct Node* nodeList;
int ID,readMB = 0;


void readMasterBook(){
    int sizeMB = sizeBookMaster();
    if(sizeMB == 0) return;
    //printf("\n inizio a leggere da: %d  pid:%d  sizeMaster:%d",readMB,getpid(),sizeMaster);
    
    for (readMB; readMB < sizeMB; readMB++)
    {
        for (int j = 0; j < SO_BLOCK_SIZE-1; j++)
        {
            if(MasterBook->blocks[readMB].transactions[j].empty == 1){
                if(MasterBook->blocks[readMB].transactions[j].sender == userList[ID].pid){
                            

                }else if(MasterBook->blocks[readMB].transactions[j].receiver == userList[ID].pid){
                             
                }
            }
        }
        
    }
}
int makeTransaction()
{   
    if(userList[ID].budgetAccount >= 2){
        struct Transaction transaction;
        transaction.empty = 1;
        strcpy(transaction.timestamp,getTime());
        int receiverID=getpid();
        int indexUser=0; 
        while(receiverID==getpid()){
        indexUser = rand()%SO_USERS_NUM;
        receiverID=userList[indexUser].pid;
        }
        //printf("\nsender %d receiver %d",getpid(),userList[indexUser].pid);
        transaction.receiver = userList[indexUser].pid;

        transaction.sender = getpid();

        int outcome = rand()%userList[ID].budgetAccount+2;
        while(outcome>userList[ID].budgetAccount)outcome = rand()%userList[ID].budgetAccount+2;

        transaction.reward= (outcome*SO_REWARD)/100; //trasformare in long
        transaction.money=outcome-transaction.reward;


        struct Message msgTransaction;
        int sendNodes=rand()%SO_NODES_NUM;
        
        msgTransaction.mtype = nodeList[sendNodes].pid;
        if((msgTransaction.mtype < (getpid() -SO_NODES_NUM-10) )|| (msgTransaction.mtype > getpid() +SO_NODES_NUM+10)) return -2;
        
        userList[ID].budgetAccount -= outcome;
        //printf("\nkey: %d    pid:%d type: %ld   sndNodes:%d",queueID,getpid(),msgTransaction.mtype,sendNodes);
        msgTransaction.pid = getpid();
        msgTransaction.tr=transaction;
        
        if(msgsnd(queueID, &msgTransaction, MSGUSER_SIZE, 0)==-1){
                perror("Error in makeTransaction ");
            }
        ++userList[ID].ntr;
        //printf("\nmsgSend:  to: %ld  money: %d  reward: %d  budgetAccount: %d   pid: %d",msgTransaction.mtype,transaction.money,transaction.reward,userList[ID].budgetAccount,getpid());
        return 0;
    }
    return -1;
}
void setQueueId(int id){
    queueID = id;
}

node_manager.c

#include "node_manager.h"
#include <stdlib.h>
#include <stdio.h>


struct User* userList;
struct Node* nodeList;
int queueID;
int ID;

void waitTransactions(int queueID)
{   
    struct Message msg;
    int num_bytes;
    int n;

     while (1)
    {
        num_bytes = msgrcv(queueID, &msg, MSGUSER_SIZE, getpid(), IPC_NOWAIT);

        if (num_bytes >= 0)
        {
            getSemaphore(SM_WRITE_NODE);
            ++nodeList[ID].trWaiting;
            releaseSemaphore(SM_WRITE_NODE);
            n = addTransaction(msg.tr);
            
            if (n < 0)
            {
                kill(msg.pid, 6); //transaction pool piena
            }
        }
        else
        {
            break;
        }
    }
}

int getRewardBlockTransactionSum(struct Block block)
{
    int sum = 0;
    for (int i = 0; i < SO_BLOCK_SIZE - 1; i++)
    {
        sum += block.transactions[i].reward;
    }
    getSemaphore(SM_WRITE_NODE);
    nodeList[ID].amount+=sum;
    releaseSemaphore(SM_WRITE_NODE);
    return sum;
}
struct Transaction createRewardTransaction(struct Block block)
{
    struct Transaction reward_transaction;

    char* time = getTime();
    strcpy(reward_transaction.timestamp,time);
    reward_transaction.sender = SENDER_REWARD;
    reward_transaction.receiver = getpid();
    reward_transaction.money = getRewardBlockTransactionSum(block);
    reward_transaction.reward = 0;
    reward_transaction.empty = 1;

    
    return reward_transaction;
}

struct Block createBlock()
{
    int i;
    struct Block block;
    
    for (int i = 0; i < SO_BLOCK_SIZE - 1; i++)
    { 
        block.transactions[i] = transaction_pool[i];
    }
    block.transactions[SO_BLOCK_SIZE - 1] = createRewardTransaction(block);
    return block;
}

definition of struct:

struct User{
    int pid; // user's pid
    int id; // position in userList
    int budgetActual; // current actual budget of the user
    int budgetAccount; // budget considering transaction not in Masterbook
    int outcome; // outcome made by transaction sent
    int income; // income made by transaction received
    int ntr; // n° transaction made
    int status; // check if a user is active
};
struct Node{
    int pid; // node's pid
    int id; //position in nodeList
    int amount; // amount of money made by rewards
    int status; // check if a node is active
    int trWaiting; // transactions in state of waiting
    int trProcessed; // number of transaction processed
};

struct Transaction
{
    int empty;
    char timestamp[150];
    int sender;
    int receiver;
    int reward;
    int money;
};
struct Message
{
    long mtype;
    pid_t pid;
    int value;
    struct Transaction tr;
};
struct Block
{
    int id;
    struct Transaction transactions[SO_BLOCK_SIZE];
};
struct Masterbook
{
    int maxBlock;
    struct Block blocks[MAX_MASTER];
};
0 Answers
Related