views:

148

answers:

3
void PacketRecord::determineAppProtocol()
{
    if (ipProtocol == IP_PROTO_UDP)
    {
        std::istringstream ss(udpData);

        std::string line;
        if (getline(ss, line) && (line.find("SIP/2.0") != std::string::npos))
        {
            appProtocol = APP_PROTO_SIP;
        }
        else
        {
            appProtocol == APP_PROTO_RTP;
        }
    }
    else
    {
        appProtocol = APP_PROTO_UNKNOWN;
    }
}

If the inner if statement fails to evaluate to true, I would expect the else block to be executed (appProtocol set to APP_PROTO_RTP). However, this does not happen. Instead, it seems the else statement is completely ignored. I can't fathom why this is the case.

As you can see from my gdb session, the first time the if statement works and appProtocol is set to APP_PROTO_SIP (as expected). the second time through, the if fails but instead of going into the else and setting appProtocol to APP_PROTO_RTP, it returns out of the function completely without setting appProtocol. appProtocol remains set to APP_PROTO_INVALID (the value it is initialized with in the PacketRecord ctor).

Breakpoint 1, PacketRecord::determineAppProtocol (this=0x805c6c8) at PacketRecord.cpp:156
156     if (ipProtocol == IP_PROTO_UDP)
(gdb) step
158         std::istringstream ss(udpData);
(gdb) 
159         std::string line;
(gdb) 
160         if (getline(ss, line) && (line.find("SIP/2.0") != std::string::npos))
(gdb) 
162             appProtocol = APP_PROTO_SIP;
(gdb) 
167         }
(gdb) 
173 }
(gdb) continue 
Continuing.

Breakpoint 1, PacketRecord::determineAppProtocol (this=0x8065388) at PacketRecord.cpp:156
156     if (ipProtocol == IP_PROTO_UDP)
(gdb) step
158         std::istringstream ss(udpData);
(gdb) 
159         std::string line;
(gdb) 
160         if (getline(ss, line) && (line.find("SIP/2.0") != std::string::npos))
(gdb) 
167         }
(gdb) 
173 }
(gdb) 
+17  A: 

You should replace

appProtocol == APP_PROTO_RTP;

by

appProtocol = APP_PROTO_RTP;

(no double equal sign)

The else statement is executed. But you are not assigning the value to appProtocol in it.

JochenJung
+1 This statement will surely be optimized out of the code, along with the encompassing branch altogether.
Steve Guidi
Right. And one should use prints instead of a debugger for such problems. A simple `cout << appProtocol << endl;` would have shown the problem.
AndiDog
Oh wow! I can't believe I didn't catch that. Thanks!
zobdos
A good compiler can also warn about errors such as that ("statement has no effect"). It helps to turn warnings on (and high).
UncleBens
@UncleBens: Good advice. I added -Wall to my makefile and got:PacketRecord.cpp: In member function ‘void PacketRecord::determineAppProtocol()’:PacketRecord.cpp:166: warning: statement has no effectAlways using -Wall from now on. :)
zobdos
@zobdos: Also a good idea to add -Werror
Martin York
+4  A: 

You're not assigning, you're comparing. Use =, not ==

Ivo van der Wijk
+2  A: 

You're using an equality statement here:

 appProtocol == APP_PROTO_RTP;

rather than an assignation.

The correct code is:

appProtocol = APP_PROTO_RTP;
babbitt