0

I have the following struct and a pointer to the struct:

struct myInfo
{
    uint16_t router_id;
    uint16_t router_port;
    uint16_t data_port;
    uint32_t router_ip_t;
    char router_ip[16];
};

struct myInfo *self;

I have the following functions:

void assignToSelf()
{
    printf("%s\n", "in assignToSelf");
    router_conn = malloc(sizeof(struct RouterConn));
    LIST_FOREACH(router_conn, &router_list, next)
    {
        if(router_conn->cost == 0)
        {
            self->router_id = router_conn->router_id;
            self->router_port = router_conn->router_port;
            self->data_port = router_conn->data_port;
            self->router_ip_t = router_conn->router_ip_t;
            strcpy(self->router_ip, router_conn->router_ip);

            int timer_fd;
            struct itimerspec timer;
            timer_fd = timerfd_create(CLOCK_REALTIME, 0);

            timer.it_value.tv_sec = update_interval;
            timer.it_value.tv_nsec = 0;
            timer.it_interval.tv_sec = 0;
            timer.it_interval.tv_nsec = 0;

            if(timerfd_settime(timer_fd, 0, &timer, NULL) < 0)
                ERROR("Error setting timer value for router!");

            router_conn->timer_val = timer_fd;
            addToList(timer_fd);
        }
    }

    printf("self->router_id: %u\n", self->router_id);
    printf("%s\n", "leaving assignToSelf");
}


void update_cost_matrix()
{
    printf("%s\n", "in update_cost_matrix");
    printf("self->router_id: %u\n", self->router_id);
    int dest, neighbor;
    uint16_t cost, mincost, nexthop;
    dest = 0;
    router_conn = malloc(sizeof(struct RouterConn));
    LIST_FOREACH(router_conn, &router_list, next)
    {
        printf("*\n");

        neighbor = 0;
        mincost = INF;
        nexthop = INF;
        if(router_conn->router_id == self->router_id) 
        {
            dest++;
            continue;
        }

        router_conn_temp = malloc(sizeof(struct RouterConn));
        LIST_FOREACH(router_conn_temp, &router_list, next)
        {
            if(router_conn_temp->isNeighbor)
            {
                if(cost_mat[self->router_id][neighbor] != INF && cost_mat[neighbor][dest] != INF)
                {
                    cost = cost_mat[self->router_id][neighbor] + cost_mat[neighbor][dest];
                    if(cost < mincost)
                    {
                        mincost = cost;
                        nexthop = router_conn_temp->router_id; 
                    }
                }
            }
            neighbor++;
        }
        router_conn->nexthop = nexthop;
        router_conn->cost = mincost;
        cost_mat[self->router_id][dest] = mincost;
        dest++;
    }
    printf("%s\n", "leaving update_cost_matrix");
}

Now, I am getting a seg fault when I am trying to access self->router_id in update_cost_matrix(), BUT only when the value of self->router_id is 5. However, it is not giving a seg fault when I am accessing the same value in the function above, that is, assignToSelf(), even though the value might be 5.

This is a code for a software defined routing, and the same code is running on various servers (the servers act as routers). The code is working fine for all routers whose self->router_id is less than 5. I am getting a seg fault only in case of a value greater than or equal to 5, that too only in the update_cost_matrix() function.

I cannot figure out a reason for this and it comes off as pretty weird. Has it got to do anything with the data type of self->router_id being uint16_t?

The output that I am getting is as below:

in assignToSelf
self->router_id: 5
leaving assignToSelf
in update_cost_matrix
Segmentation fault

EDIT : I have initialized the pointer to the struct self prior to this function call, at the very beginning, in the following way:

self = (struct myInfo*)malloc(sizeof(struct myInfo));

xertzer
  • 69
  • 6
  • 1
    `self` is pointing to some valid memory? – user2736738 Dec 02 '17 at 07:48
  • From what you show `struct myInfo *self;` is never initialised. As it stands it points nowhere, so dereferencing it like `self->router_id = ...` invokes undefined behaviour. From then on ***anything*** can happen, from *seemingly* working to crash. – alk Dec 02 '17 at 07:52
  • @coderredoc Yes. I am telling you, it works fine for all self->router_id values less than 5. It throws a seg fault only when the self->router_id value is greater than or equal to 5. I know cause, the simulator ends whenever there is an error. Now if I put the router_id of the first router to be 5, the simulator ends there itself. Otherwise, the simulator ends at the router with router_id 5. – xertzer Dec 02 '17 at 07:52
  • @alk I have initialized the pointer to the struct `self` in the following way at the beginning itself: `self = (struct myInfo*)malloc(sizeof(struct myInfo));` – xertzer Dec 02 '17 at 07:53
  • @alk Do I need to initialize the specific variables of the struct as well? – xertzer Dec 02 '17 at 07:54
  • @xertzer.: Let's see the code.Post the full code. – user2736738 Dec 02 '17 at 07:55
  • Well, then the code seems to be invoking undefined behaviour somewhere else. Probably inside the code you do not show us. So you might like to consider running the code using a memory checker like [Valgrind](http://valgrind.org). – alk Dec 02 '17 at 07:55
  • using an uninitialized pointer yields undefined/unpredictable behavior. The number `5` may just happen by chance. It may also be due to the way you initialize `self`. Can you please update your question to show how you initialize `self`? Also, do you have valgrind available on your platform? If so, compile for debug, and run it through valgrind. – lockcmpxchg8b Dec 02 '17 at 07:55
  • 1
    OT: There Is No Need To Cast To/From `void`-Pointers In C. – alk Dec 02 '17 at 07:58
  • `router_conn->router_ip` is it of length >16? – user2736738 Dec 02 '17 at 07:58
  • 1
    When you say 'access self->router_id`, do you mean the `printf` at the top of `update_cost_matrix`, or it's use as a subscript to `cost_mat`? (If the latter, how do you declare `cost_mat`? – lockcmpxchg8b Dec 02 '17 at 08:01
  • @coderredoc No. It's 16, exactly. A char array of length 16. But, the seg fault I am getting is in self->router_id. – xertzer Dec 02 '17 at 08:01
  • @lockcmpxchg8b printf at the top of update_cost_matrix. Like, it's not going any further, if you see and match the output I provided. So I know that's where it is giving me the seg fault. router_conn->router_id isn't, as I can print that value. – xertzer Dec 02 '17 at 08:03
  • @xertzer.: You will get better help if you show relevant codes. – user2736738 Dec 02 '17 at 08:03
  • 1
    You may want to review: [Is it a good idea to **typedef** pointers?](http://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers). – David C. Rankin Dec 02 '17 at 08:05
  • There is no relationship between `assignToSelf` and `update_cost_matrix`. Whatever happens to `self` happens in the code between these two calls. – lockcmpxchg8b Dec 02 '17 at 08:14

0 Answers0