Thanks, Michael, please the see the following:
....
Note: Many people who post code look-alikes leave out the critical
parts so the original code is really necessary if you cannot
break it down to a minimal example.
Ok, I've put the source of the problematic function at the end.
Is the place in the parameter lists where you pass unacked_cb
or the address of unacked_cb->time const qualified? Otherwise
I would say try it. Your compiler may tell you interesting
things about it.
I did not put const qualifier. But I just did and compiled without
any warning or error. NOTE: it is not the contents of "unacked_cb"
gets changed, but the pointer itself gets incremented unexpected.
I tried: retran_unacked(RRR_SENT_UNACKED_CB * const unacked_cb CCXT_T CXT)
without any warning with compiler.
Okay, this is somewhat offtopic:
<OT>
You claim to have tried finding the error with about any other means,
so I have only one suggestion now:
Find out the addresses where things are stored and watch the contents
with hardware watchpoints. Example:
--------------
$ print &object
0xdeadbeef
$ watch *((struct objtype *)0xdeadbeef)
--------------
Important is to use the actual "address", otherwise the watchpoint
will cease existance after leaving the function where it was defined.
You have to delete the hardware watchpoints before a new run.
</OT>
The problem here is that unacked_cb is a pointer pointing to a dynamically
allocated memory and there many such pointers. Before the problem occurs,
I don't know which one will have the problem. Therefore, it is not possible
to type the debug command beforehand. I hope the "watch" function can be
coded into the c code to ensure every such pointer will not get changed
during its life cycle.
Notice the remarks I put behand "<--------" signs. The struct of
RRR_SENT_UNACKED_CB really has nothing specially. It has some pointers and
ints defined inside. But in this case, I guess it is irrelavent since we are talking
pointer itself's change, not its content's change.
Thanks lot.
-SZ
Here is the source code:
void
retran_unacked(RRR_SENT_UNACKED_CB *unacked_cb CCXT_T CXT)
{
RRR_NEXT_HOP_CB *next_hop = unacked_cb->next_hop_cb;
int frr_rc;
PSB *psbp;
next_hop->nh_event_usage_count++; <---- next_hop is correct,
so unacked_cb is ok here.
if (RPL_RL && (unacked_cb->sa_resend_attempts >= RPL_RL))
{
if ((unacked_cb->sa_pkt_msg_type == PATH) ||
(unacked_cb->sa_pkt_msg_type == RESV))
{
frr_rc = RRR_FRR_CONTINUE;
if (RRR_EX_FAST_REROUTE())
{
frr_rc = rrr_frr_proc_sent_unacked_msg(
unacked_cb->sa_pkt_msg_type,
unacked_cb->spi_msg_id_info->msg_id_psb_parent CCXT);
}
if (frr_rc == RRR_FRR_CONTINUE)
{
rrr_maybe_send_error_packet(unacked_cb->sa_pkt_msg_type,
unacked_cb->sa_state_handle,
unacked_cb->sa_upstrm_lih_set,
unacked_cb->sa_upstrm_lih
CCXT);
}
}
rrr_delete_sent_unacked_cb(unacked_cb, next_hop CCXT);
}
else
{
rrr_resend_packet(unacked_cb, next_hop CCXT);
if (next_hop->nh_use_msg_ids == ATG_NO)
{
rrr_delete_sent_unacked_cb(unacked_cb, next_hop CCXT);
}
else
{
unacked_cb->sa_resend_attempts++;
if (next_hop->nh_rr_decay != 100) {
unacked_cb->sa_retrans_interval *=
(100 + next_hop->nh_rr_decay);
unacked_cb->sa_retrans_interval /= 100;
} else {
unacked_cb->sa_retrans_interval =
unacked_cb->sa_retrans_interval << 1;
}
if (unacked_cb->sa_pkt_msg_type == PATH_TEAR) {
if (!unacked_cb->spi_msg_id_info) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
psbp = sent_unacked_cb->spi_msg_id_info->msg_id_psb_parent;
if (!psbp) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
if (psbp->rapid_retran & RPL_PATH_TEAR) {
psbp->rapid_retran &= ~(RPL_PATH_TEAR|RPL_PATH_ERROR);
rrr_delete_retries_for_psb(psbp,
RRR_KILL_RETRY_FOR_ALL_MSGS CCXT);
deferred_kill_PSB(psbp CCXT);
}
goto EXIT_LABEL;
}
if (unacked_cb->sa_retrans_interval >= RPL_RM) {
if (unacked_cb->sa_pkt_msg_type == PATH_TEAR) {
if (!unacked_cb->spi_msg_id_info) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
psbp = sent_unacked_cb->spi_msg_id_info->msg_id_psb_parent;
if (!psbp) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
if (psbp->rapid_retran & RPL_PATH_TEAR) {
psbp->rapid_retran &=
~(RPL_PATH_TEAR|RPL_PATH_ERROR);
rrr_delete_retries_for_psb(psbp,
RRR_KILL_RETRY_FOR_ALL_MSGS CCXT);
deferred_kill_PSB(psbp CCXT);
}
goto EXIT_LABEL;
} else if (unacked_cb->sa_pkt_msg_type == PATH_ERR){
if (!unacked_cb->spi_msg_id_info) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
psbp = sent_unacked_cb->spi_msg_id_info->msg_id_psb_parent;
if (!psbp) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
if (psbp->rapid_retran & RPL_PATH_ERROR) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
psbp->rapid_retran &= ~RPL_PATH_ERROR;
frr_rc = rrr_frr_proc_path_tear(psbp,
ATG_MPLS_XC_REL_REAS_IF_DOWN,
TRUE
CCXT);
if (frr_rc == RRR_FRR_CONTINUE) {
psbp->ps_rel_reason = ATG_MPLS_XC_REL_REAS_IF_DOWN;
tear_or_kill_PSB(psbp CCXT);
}
}
goto EXIT_LABEL;
} else if (unacked_cb->sa_pkt_msg_type == RESV_TEAR){
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
} else if (unacked_cb->sa_pkt_msg_type == RESV_ERR) {
rrr_delete_sent_unacked_cb(unacked_cb,
next_hop CCXT);
goto EXIT_LABEL;
}
unacked_cb->sa_retrans_interval = RPL_RF;
}
unacked_cb->sa_resend_time =
unacked_cb->sa_retrans_interval;
mTimerInsert(&unacked_cb->m_timer, (vfcnptr_2)retran_unacked,
unacked_cb,unacked_cb->sa_resend_time, TTYPE_ONESHOT); <------
The stack shows that
both &unacked_cb->m_timer
and unacked_cb are added by 1.
}
}
EXIT_LABEL:
next_hop->nh_event_usage_count--;
rrr_maybe_free_next_hop(next_hop CCXT);
return;
} /* retran_unacked */