Bug 1055852 - Plug bunches of leaks that signaling_unittest hits, mostly in sipcc. r=mccr8
authorByron Campen [:bwc] <docfaraday@gmail.com>
Thu, 21 Aug 2014 15:11:19 -0700
changeset 223955 103cf4c29d7f82f8e005eeb3ffd9781ec604a16a
parent 223954 0849d066f121d01720597584b511b8e9178909fb
child 223956 5f66dd3d63f2d6ab511231084c7e61fefed5c1ea
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1055852
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1055852 - Plug bunches of leaks that signaling_unittest hits, mostly in sipcc. r=mccr8
media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h
media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
media/webrtc/signaling/src/sipcc/core/common/init.c
media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
media/webrtc/signaling/src/sipcc/core/gsm/lsm.c
media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c
media/webrtc/signaling/test/FakeMediaStreams.h
media/webrtc/signaling/test/FakePCObserver.h
media/webrtc/signaling/test/signaling_unittests.cpp
--- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
+++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
@@ -1270,18 +1270,27 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
         ccsdpCodecName(payloads[i].codec_type),
         payloads[i].audio.frequency,
         payloads[i].audio.packet_size,
         payloads[i].audio.channels,
         payloads[i].audio.bitrate);
       configs.push_back(config_raw);
     }
 
-    if (conduit->ConfigureRecvMediaCodecs(configs))
+    auto error = conduit->ConfigureRecvMediaCodecs(configs);
+
+    // Would be nice to use a smart container, but we'd need to change
+    // a lot of code.
+    for (auto it = configs.begin(); it != configs.end(); ++it) {
+      delete *it;
+    }
+
+    if (error) {
       return VCM_ERROR;
+    }
 
     // Now we have all the pieces, create the pipeline
     mozilla::RefPtr<mozilla::MediaPipelineReceiveAudio> pipeline =
       new mozilla::MediaPipelineReceiveAudio(
         pc.impl()->GetHandle(),
         pc.impl()->GetMainThread().get(),
         pc.impl()->GetSTSThread(),
         stream->GetMediaStream()->GetStream(),
@@ -1325,23 +1334,33 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
 
     for(int i=0; i <num_payloads; i++)
     {
       config_raw = new mozilla::VideoCodecConfig(
         payloads[i].local_rtp_pt,
         ccsdpCodecName(payloads[i].codec_type),
         payloads[i].video.rtcp_fb_types);
       if (vcmEnsureExternalCodec(conduit, config_raw, false)) {
+        delete config_raw;
         continue;
       }
       configs.push_back(config_raw);
     }
 
-    if (conduit->ConfigureRecvMediaCodecs(configs))
+    auto error = conduit->ConfigureRecvMediaCodecs(configs);
+
+    // Would be nice to use a smart container, but we'd need to change
+    // a lot of code.
+    for (auto it = configs.begin(); it != configs.end(); ++it) {
+      delete *it;
+    }
+
+    if (error) {
       return VCM_ERROR;
+    }
 
     // Now we have all the pieces, create the pipeline
     mozilla::RefPtr<mozilla::MediaPipelineReceiveVideo> pipeline =
         new mozilla::MediaPipelineReceiveVideo(
             pc.impl()->GetHandle(),
             pc.impl()->GetMainThread().get(),
             pc.impl()->GetSTSThread(),
             stream->GetMediaStream()->GetStream(),
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -1318,32 +1318,32 @@ static void AddTrackAndListener(MediaStr
         MOZ_MTLOG(ML_DEBUG, "added track @ " << current_end <<
                   " -> " << mStream->StreamTimeToSeconds(current_end));
       }
 
       // To avoid assertions, we need to insert a dummy segment that covers up
       // to the "start" time for the track
       segment_->AppendNullData(current_ticks);
       mStream->AsSourceStream()->AddTrack(track_id_, track_rate_,
-                                          current_ticks, segment_);
+                                          current_ticks, segment_.forget());
       // AdvanceKnownTracksTicksTime(HEAT_DEATH_OF_UNIVERSE) means that in
       // theory per the API, we can't add more tracks before that
       // time. However, the impl actually allows it, and it avoids a whole
       // bunch of locking that would be required (and potential blocking)
       // if we used smaller values and updated them on each NotifyPull.
       mStream->AsSourceStream()->AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
       // We need to know how much has been "inserted" because we're given absolute
       // times in NotifyPull.
       completed_->TrackAdded(current_ticks);
     }
    private:
     TrackID track_id_;
     TrackRate track_rate_;
-    MediaSegment* segment_;
+    nsAutoPtr<MediaSegment> segment_;
     nsRefPtr<MediaStreamListener> listener_;
     const RefPtr<TrackAddedCallback> completed_;
   };
 
   MOZ_ASSERT(listener);
 
   source->GraphImpl()->AppendMessage(new Message(source, track_id, track_rate, segment, listener, completed));
 #else
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -250,16 +250,17 @@ public:
         mFsmState(aInfo->getFsmState()),
         mStateStr(aInfo->callStateToString(mCallState)),
         mFsmStateStr(aInfo->fsmStateToString(mFsmState)) {
     if (mCallState == REMOTESTREAMADD) {
       MediaStreamTable *streams = nullptr;
       streams = aInfo->getMediaStreams();
       mRemoteStream = mPC->media()->GetRemoteStream(streams->media_stream_id);
       MOZ_ASSERT(mRemoteStream);
+      cpr_free(streams);
     } else if (mCallState == FOUNDICECANDIDATE) {
         mCandidateStr = aInfo->getCandidate();
     } else if ((mCallState == CREATEOFFERSUCCESS) ||
                (mCallState == CREATEANSWERSUCCESS)) {
         mSdpStr = aInfo->getSDP();
     }
   }
 
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -135,16 +135,17 @@ class IceConfiguration
 public:
   bool addStunServer(const std::string& addr, uint16_t port)
   {
     NrIceStunServer* server(NrIceStunServer::Create(addr, port));
     if (!server) {
       return false;
     }
     addStunServer(*server);
+    delete server;
     return true;
   }
   bool addTurnServer(const std::string& addr, uint16_t port,
                      const std::string& username,
                      const std::string& pwd,
                      const char* transport)
   {
     // TODO(ekr@rtfm.com): Need support for SASLprep for
@@ -152,16 +153,17 @@ public:
     std::vector<unsigned char> password(pwd.begin(), pwd.end());
 
     NrIceTurnServer* server(NrIceTurnServer::Create(addr, port, username, password,
                                                     transport));
     if (!server) {
       return false;
     }
     addTurnServer(*server);
+    delete server;
     return true;
   }
   void addStunServer(const NrIceStunServer& server) { mStunServers.push_back (server); }
   void addTurnServer(const NrIceTurnServer& server) { mTurnServers.push_back (server); }
   const std::vector<NrIceStunServer>& getStunServers() const { return mStunServers; }
   const std::vector<NrIceTurnServer>& getTurnServers() const { return mTurnServers; }
 private:
   std::vector<NrIceStunServer> mStunServers;
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.c
@@ -143,63 +143,60 @@ DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_Ap
     result = strlib_malloc(translatedString, strlen(translatedString));
     return result;
 }
 
 /**
  * Before initing the line_info release any memory which has been used
  * so we do not leak any here.
  */
-void ccsnap_line_pre_init () {
+void ccsnap_line_free () {
     int i;
 
-    CCAPP_DEBUG(DEB_F_PREFIX"Entering line_pre_init to clear it out to avoid mem leaks", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_line_pre_init"));
+    CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__));
 
-    for (i=1;i<MAX_CONFIG_LINES;i++) {
-        if ((lineInfo[i].name) && (strlen(lineInfo[i].name) > 0)) {
+    for (i=1;i<=MAX_CONFIG_LINES;i++) {
+        if (lineInfo[i].name) {
             strlib_free(lineInfo[i].name);
         }
-        if ((lineInfo[i].dn) && (strlen(lineInfo[i].dn) > 0)) {
+        if (lineInfo[i].dn) {
             strlib_free(lineInfo[i].dn);
         }
-        if ((lineInfo[i].cfwd_dest) && (strlen(lineInfo[i].cfwd_dest) > 0)) {
+        if (lineInfo[i].cfwd_dest) {
             strlib_free(lineInfo[i].cfwd_dest);
         }
-        if ((lineInfo[i].externalNumber) &&
-            (strlen(lineInfo[i].externalNumber) > 0)) {
+        if (lineInfo[i].externalNumber) {
             strlib_free(lineInfo[i].externalNumber);
         }
-        if ((featureInfo[i].speedDialNumber) &&
-            (strlen(featureInfo[i].speedDialNumber) > 0)) {
+        if (featureInfo[i].speedDialNumber) {
             strlib_free(featureInfo[i].speedDialNumber);
         }
-        if ((featureInfo[i].contact) && (strlen(featureInfo[i].contact) > 0)) {
+        if (featureInfo[i].contact) {
             strlib_free(featureInfo[i].contact);
         }
-        if ((featureInfo[i].name) && (strlen(featureInfo[i].name) > 0)) {
+        if (featureInfo[i].name) {
             strlib_free(featureInfo[i].name);
         }
-        if ((featureInfo[i].retrievalPrefix) &&
-            (strlen(featureInfo[i].retrievalPrefix) > 0)) {
+        if (featureInfo[i].retrievalPrefix) {
             strlib_free(featureInfo[i].retrievalPrefix);
         }
     }
 }
 
 /**
  * Initialize lineinfo and featureinfo arrays
  */
 void ccsnap_line_init() {
    int i;
    cc_uint32_t tmpInt;
    char tempStr[MAX_URL_LENGTH];
    char maskStr[MAX_EXTERNAL_NUMBER_MASK_SIZE];
 
    /* clean up structure if need be */
-   ccsnap_line_pre_init();
+   ccsnap_line_free();
 
    memset(lineInfo, 0, MAX_CONFIG_LINES*sizeof(cc_line_info_t));
    memset(featureInfo, 0, MAX_CONFIG_LINES*sizeof(cc_feature_info_t));
    for (i=1;i<=MAX_CONFIG_LINES;i++) {
       config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i);
       if ( tmpInt == cfgLineFeatureDN ) {
           lineInfo[i].button = i;
           lineInfo[i].line_type = tmpInt;
@@ -317,39 +314,38 @@ cc_feature_info_t* ccsnap_getFeatureInfo
 	}
 
      return NULL;
 }
 
 /**
  * Release any used mem to avoid a leak.
  */
-void ccsnap_device_pre_init () {
+void ccsnap_device_free () {
     int i = 0;
 
-    CCAPP_DEBUG(DEB_F_PREFIX"Entering device_pre_init to clear it out to avoid mem leaks", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_device_pre_init"));
-    if ((g_deviceInfo.not_prompt) && (strlen(g_deviceInfo.not_prompt) > 0)) {
+    CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__));
+    if (g_deviceInfo.not_prompt) {
         strlib_free(g_deviceInfo.not_prompt);
     }
 
     i = 0;
     while (i < CCAPI_MAX_SERVERS) {
-        if ((g_deviceInfo.ucm[i].name) &&
-            (strlen(g_deviceInfo.ucm[i].name) > 0)) {
+        if (g_deviceInfo.ucm[i].name) {
             strlib_free(g_deviceInfo.ucm[i].name);
         }
         i++;
     }
 }
 
 void ccsnap_device_init() {
    char temp[MAX_SIP_URL_LENGTH];
 
    /* clean up structure if need be */
-   ccsnap_device_pre_init();
+   ccsnap_device_free();
 
    memset (&g_deviceInfo, 0, sizeof(g_deviceInfo));
    g_deviceInfo.not_prompt =strlib_empty();
 
    g_deviceInfo.not_prompt_prio = 0;
    g_deviceInfo.not_prompt_prog = 0;
    g_deviceInfo.mwi_lamp = FALSE;
    g_deviceInfo.cucm_mode = CC_MODE_CCM;
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_snapshot.h
@@ -87,17 +87,19 @@ typedef struct accessory_cfg_info_t_ {
 
 extern accessory_cfg_info_t g_accessoryCfgInfo;
 extern cc_device_info_t g_deviceInfo;
 extern cc_line_info_t lineInfo[MAX_CONFIG_LINES+1];
 
 cc_line_info_t* ccsnap_getLineInfo(int lineID);
 cc_line_info_t* ccsnap_getLineInfoFromBtn(int btnID);
 void ccsnap_line_init();
+void ccsnap_line_free();
 void ccsnap_device_init();
+void ccsnap_device_free();
 void ccsnap_gen_deviceEvent(ccapi_device_event_e event, cc_device_handle_t handle);
 void ccsnap_gen_lineEvent(ccapi_line_event_e event, cc_lineid_t handle);
 void ccsnap_gen_callEvent(ccapi_call_event_e event, cc_call_handle_t handle);
 void ccsnap_update_ccm_status(cc_string_t addr, cc_ccm_status_t status);
 void ccsnap_handle_mnc_reached (cc_line_info_t *line_info,
 		 cc_boolean mnc_reached, cc_cucm_mode_t mode);
 cc_feature_info_t* ccsnap_getFeatureInfo(int featureIndex);
 void ccsnap_gen_blfFeatureEvent(cc_blf_state_t state, int appId);
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
@@ -1014,16 +1014,18 @@ void CCApp_processCmds(unsigned int cmd,
             ccsnap_line_init();
             ccapp_set_state(CC_OOS_REGISTERING);
             send_protocol_config_msg();
             break;
          case CMD_SHUTDOWN:
          case CMD_UNREGISTER_ALL_LINES:
             /* send a shutdown message to the SIP Task */
             SIPTaskPostShutdown(SIP_EXTERNAL, reason, reasonStr);
+            ccsnap_line_free();
+            ccsnap_device_free();
             break;
          case CMD_RESTART:
             SIPTaskPostRestart(TRUE);
             break;
          case CMD_BLF_INIT:
             pres_sub_handler_initialized();
             break;
          default:
@@ -1500,16 +1502,17 @@ static void ccappUpdateSessionData (sess
                 /* Fall through to the next case... */
             case REMOTE_STREAM_ADD:
                 data->cause =
                     sessUpd->update.ccSessionUpd.data.state_data.cause;
                 data->media_stream_track_id = sessUpd->update.ccSessionUpd.data.
                     state_data.media_stream_track_id;
                 data->media_stream_id = sessUpd->update.ccSessionUpd.data.
                     state_data.media_stream_id;
+                strlib_free(data->status);
                 data->status =
                   sessUpd->update.ccSessionUpd.data.state_data.reason_text;
                 break;
             default:
                 break;
         }
 
         /*
@@ -1756,16 +1759,17 @@ static void ccappUpdateSessionData (sess
 	case CALL_STATUS:
 	/*
 	 * For 5th Gen Phones, data->status is localized.
 	 * 3rd Gen and 4th Gen phones should use sessUpd->update struct to pass the status to the application.
 	 */
 	data->status = ccsnap_EscapeStrToLocaleStr(data->status, sessUpd->update.ccSessionUpd.data.status.status, LEN_UNKNOWN);
         if (data->status != NULL) {
             if(strncmp(data->status, UNKNOWN_PHRASE_STR, UNKNOWN_PHRASE_STR_SIZE) == 0){
+                    strlib_free(data->status);
                     data->status = strlib_empty();
             }
             if(strcmp(data->status, strlib_empty()) != 0){
                     ccsnap_gen_callEvent(CCAPI_CALL_EV_STATUS, CREATE_CALL_HANDLE_FROM_SESSION_ID(sessUpd->sessionID));
             }
         }
         //<Added for automation test purpose, <CallStatusChanged>
         NOTIFY_CALL_DEBUG(DEB_NOTIFY_PREFIX"[line=%d][call.ref=%d][status=%s]",
@@ -1842,19 +1846,21 @@ static void ccappUpdateSessionData (sess
     case SET_LOCAL_DESC:
     case SET_REMOTE_DESC:
     case UPDATE_LOCAL_DESC:
     case UPDATE_REMOTE_DESC:
     case ICE_CANDIDATE_ADD:
     case ICE_CANDIDATE_FOUND:
 	if (sessUpd->update.ccSessionUpd.data.state_data.extra) {
 	    if (sessUpd->eventID == ICE_CANDIDATE_FOUND) {
+                strlib_free(data->candidate);
 		data->candidate = sessUpd->update.ccSessionUpd.data.state_data.extra;
 	    }
 	}
+        strlib_free(data->sdp);
         data->sdp = sessUpd->update.ccSessionUpd.data.state_data.sdp;
         /* Fall through to the next case... */
     case REMOTE_STREAM_ADD:
         data->timecard = sessUpd->update.ccSessionUpd.data.state_data.timecard;
         data->cause = sessUpd->update.ccSessionUpd.data.state_data.cause;
         data->state = sessUpd->update.ccSessionUpd.data.state_data.state;
         data->fsm_state =
             sessUpd->update.ccSessionUpd.data.state_data.fsm_state;
--- a/media/webrtc/signaling/src/sipcc/core/common/init.c
+++ b/media/webrtc/signaling/src/sipcc/core/common/init.c
@@ -399,16 +399,20 @@ send_task_unload_msg(cc_srcs_t dest_id)
             if (ccappTaskPostMsg(CCAPP_THREAD_UNLOAD, msg, len, CCAPP_CCPROVIER) == CPR_FAILURE )
             {
                 CSFLogError("common",
                   "%s: Unable to send THREAD_UNLOAD msg to CCapp thread",
                   fname);
             }
             CSFLogError("common", "%s:  send UNLOAD msg to CCapp thread good",
               fname);
+            /* Unlike other similar functions, ccappTaskPostMsg does not take
+             * ownership. */
+            cpr_free(msg);
+            msg = NULL;
         }
         break;
 
         default:
             CSFLogError("common", "%s: Unknown destination task passed=%d.",
               fname, dest_id);
         break;
     }
--- a/media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/ccapi.c
@@ -1211,19 +1211,20 @@ static void send_message_helper(
     if (msg_id == CC_MSG_SETLOCALDESC || msg_id == CC_MSG_SETREMOTEDESC) {
         pmsg->action = action;
     }
 
     if (sdp &&
         (msg_id == CC_MSG_CREATEANSWER ||
          msg_id == CC_MSG_SETLOCALDESC ||
          msg_id == CC_MSG_SETREMOTEDESC)) {
-        size_t sdp_size = strlen(sdp) + 1;
-        pmsg->sdp = cpr_malloc(sdp_size);
-        sstrncpy(pmsg->sdp, sdp, sdp_size);
+        /* This is safe because all of the queueing has been removed.
+         * From a few minutes of looking, it appears to be very messy to
+         * clean this up down in the implementation. */
+        pmsg->sdp = sdp;
     } else {
         pmsg->sdp = NULL;
     }
 
     if (pmsg->data_valid == TRUE) {
         pmsg->data = *data;
         /*
          * For call Info feature, need to copy the caller ID
--- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
@@ -4046,17 +4046,17 @@ fsmdef_ev_addcandidate(sm_event_t *event
             "candidate.");
         return (SM_RC_END);
     }
 
     ui_ice_candidate_add(evAddIceCandidate, fcb->state, line, call_id,
         dcb->caller_id.call_instance_id, strlib_malloc(remote_sdp,-1),
         msg->timecard, PC_NO_ERROR, NULL);
 
-    free(remote_sdp);
+    cpr_free(remote_sdp);
     return (SM_RC_END);
 }
 
 
 static sm_rcs_t
 fsmdef_ev_foundcandidate(sm_event_t *event) {
     fsm_fcb_t           *fcb = (fsm_fcb_t *) event->data;
     fsmdef_dcb_t        *dcb = fcb->dcb;
@@ -4125,16 +4125,17 @@ fsmdef_ev_foundcandidate(sm_event_t *eve
                 (char *)msg->data.candidate.mid,
                 (char *)msg->data.candidate.candidate);
 
     ui_ice_candidate_found(evFoundIceCandidate, fcb->state, line, call_id,
         dcb->caller_id.call_instance_id, strlib_malloc(local_sdp,-1),
         strlib_malloc(candidate_tmp, -1),
         msg->timecard, PC_NO_ERROR, NULL);
 
+    cpr_free(local_sdp);
     return SM_RC_END;
 }
 
 
 static void
 fsmdef_check_active_feature (fsmdef_dcb_t *dcb, cc_features_t ftr_id)
 {
     if ((dcb) && (dcb->active_feature != ftr_id)) {
@@ -9004,16 +9005,17 @@ fsmdef_init (void)
 void
 fsmdef_shutdown (void)
 {
     fsmdef_dcb_t *dcb;
 
     FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) {
         /* clean media list */
         gsmsdp_clean_media_list(dcb);
+        gsmsdp_free(dcb);
     }
 
     /* destroy free media structure list */
     gsmsdp_destroy_free_media_list();
 
     cpr_free(fsmdef_dcbs);
     fsmdef_dcbs = NULL;
 }
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
@@ -444,16 +444,23 @@ gsmsdp_free_media (fsmdef_media_t *media
       vcmFreeMediaPtr(media->video);
     }
 
     if(media->payloads != NULL) {
         cpr_free(media->payloads);
         media->payloads = NULL;
         media->num_payloads = 0;
     }
+
+    if (media->previous_sdp.payloads != NULL) {
+        cpr_free(media->previous_sdp.payloads);
+        media->previous_sdp.payloads = NULL;
+        media->previous_sdp.num_payloads = 0;
+    }
+
     /*
      * Check to see if the element is part of the
      * free chunk space.
      */
     if ((media >= &gsmsdp_free_media_chunk[0]) &&
         (media <= &gsmsdp_free_media_chunk[GSMSDP_PERM_MEDIA_ELEMS-1])) {
         /* the element is part of free chunk, put it back to the list */
         (void)sll_lite_link_head(&gsmsdp_free_media_list,
@@ -7359,19 +7366,36 @@ gsmsdp_configure_dtls_data_attributes(fs
  * course of the call.
  *
  * Parameters:
  * dcb_p    - pointer to fsmdef_dcb_t.
  */
 void
 gsmsdp_free (fsmdef_dcb_t *dcb_p)
 {
-    if ((dcb_p != NULL) && (dcb_p->sdp != NULL)) {
-        sipsdp_free(&dcb_p->sdp);
-        dcb_p->sdp = NULL;
+    if (dcb_p != NULL) {
+        if (dcb_p->sdp != NULL) {
+            sipsdp_free(&dcb_p->sdp);
+            dcb_p->sdp = NULL;
+        }
+
+        if (dcb_p->media_cap_tbl) {
+            cpr_free(dcb_p->media_cap_tbl);
+            dcb_p->media_cap_tbl = NULL;
+        }
+
+        if (dcb_p->remote_media_stream_tbl) {
+            cpr_free(dcb_p->remote_media_stream_tbl);
+            dcb_p->remote_media_stream_tbl = NULL;
+        }
+
+        if (dcb_p->local_media_track_tbl) {
+            cpr_free(dcb_p->local_media_track_tbl);
+            dcb_p->local_media_track_tbl = NULL;
+        }
     }
 }
 
 /*
  * gsmsdp_sdp_differs_from_previous_sdp
  *
  * Description:
  *
--- a/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c
@@ -642,16 +642,17 @@ lsm_open_rx (lsm_lcb_t *lcb, cc_action_d
             lsm_get_ms_ui_call_handle(lcb->line, lcb->call_id, lcb->ui_id),
             dcb->peerconnection,
             media->level,
             &default_addr, &port_allocated,
             &candidates, &candidate_ct);
 
           if (!status) {
             sstrncpy(dcb->ice_default_candidate_addr, default_addr, sizeof(dcb->ice_default_candidate_addr));
+            cpr_free(default_addr);
 
             data->port = (uint16_t)port_allocated;
             media->candidate_ct = candidate_ct;
             media->candidatesp = candidates;
             rc = CC_RC_SUCCESS;
           }
         }
       }
--- a/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c
+++ b/media/webrtc/signaling/src/sipcc/core/sipstack/ccsip_sdp.c
@@ -330,16 +330,17 @@ sipsdp_write_to_buf (sdp_t *sdp_info, ui
     flex_string fs;
     uint32_t sdp_len;
     sdp_result_e rc;
 
     flex_string_init(&fs);
 
     if (!sdp_info) {
         CCSIP_DEBUG_ERROR(SIP_F_PREFIX"NULL sdp_info or src_sdp", __FUNCTION__);
+        flex_string_free(&fs);
         return (NULL);
     }
 
     if ((rc = sdp_build(sdp_info, &fs))
         != SDP_SUCCESS) {
         CCSIP_DEBUG_TASK(DEB_F_PREFIX"sdp_build rc=%s", DEB_F_PREFIX_ARGS(SIP_SDP, __FUNCTION__),
                          sdp_get_result_name(rc));
 
--- a/media/webrtc/signaling/test/FakeMediaStreams.h
+++ b/media/webrtc/signaling/test/FakeMediaStreams.h
@@ -127,17 +127,19 @@ class Fake_SourceMediaStream : public Fa
  public:
   Fake_SourceMediaStream() : mSegmentsAdded(0),
                              mDesiredTime(0),
                              mPullEnabled(false),
                              mStop(false),
                              mPeriodic(new Fake_MediaPeriodic(this)) {}
 
   void AddTrack(mozilla::TrackID aID, mozilla::TrackRate aRate, mozilla::TrackTicks aStart,
-                mozilla::MediaSegment* aSegment) {}
+                mozilla::MediaSegment* aSegment) {
+    delete aSegment;
+  }
   void EndTrack(mozilla::TrackID aID) {}
 
   bool AppendToTrack(mozilla::TrackID aID, mozilla::MediaSegment* aSegment,
                      mozilla::MediaSegment *aRawSegment) {
     return AppendToTrack(aID, aSegment);
   }
 
   bool AppendToTrack(mozilla::TrackID aID, mozilla::MediaSegment* aSegment) {
--- a/media/webrtc/signaling/test/FakePCObserver.h
+++ b/media/webrtc/signaling/test/FakePCObserver.h
@@ -56,17 +56,17 @@ public:
     pc(peerConnection) {
   }
 
   virtual ~AFakePCObserver() {}
 
   std::vector<mozilla::DOMMediaStream *> GetStreams() { return streams; }
 
   ResponseState state;
-  char *lastString;
+  std::string lastString;
   sipcc::PeerConnectionImpl::Error lastStatusCode;
   mozilla::dom::PCObserverStateType lastStateType;
   int addIceSuccessCount;
   bool onAddStreamCalled;
   std::string name;
   std::vector<std::string> candidates;
 
   virtual NS_IMETHODIMP OnCreateOfferSuccess(const char* offer, ER&) = 0;
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -280,17 +280,17 @@ public:
   NS_IMETHODIMP OnIceCandidate(uint16_t level, const char *mid, const char *cand, ER&);
 };
 
 NS_IMPL_ISUPPORTS(TestObserver, nsISupportsWeakReference)
 
 NS_IMETHODIMP
 TestObserver::OnCreateOfferSuccess(const char* offer, ER&)
 {
-  lastString = strdup(offer);
+  lastString = offer;
   state = stateSuccess;
   std::cout << name << ": onCreateOfferSuccess = " << std::endl << indent(offer)
             << std::endl;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TestObserver::OnCreateOfferError(uint32_t code, const char *message, ER&)
@@ -300,17 +300,17 @@ TestObserver::OnCreateOfferError(uint32_
   std::cout << name << ": onCreateOfferError = " << code
             << " (" << message << ")" << std::endl;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TestObserver::OnCreateAnswerSuccess(const char* answer, ER&)
 {
-  lastString = strdup(answer);
+  lastString = answer;
   state = stateSuccess;
   std::cout << name << ": onCreateAnswerSuccess =" << std::endl
             << indent(answer) << std::endl;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TestObserver::OnCreateAnswerError(uint32_t code, const char *message, ER&)
@@ -1043,35 +1043,39 @@ class SignalingAgent {
 
     return o.find(str) != std::string::npos;
   }
 
   size_t MatchingCandidates(const std::string& cand) {
     return pObserver->MatchingCandidates(cand);
   }
 
-  char* offer() const { return offer_; }
-  char* answer() const { return answer_; }
+  const char* offer() const { return offer_.c_str(); }
+  const char* answer() const { return answer_.c_str(); }
 
   std::string getLocalDescription() const {
     char *sdp = nullptr;
     pc->GetLocalDescription(&sdp);
     if (!sdp) {
       return "";
     }
-    return sdp;
+    std::string result(sdp);
+    delete sdp;
+    return result;
   }
 
   std::string getRemoteDescription() const {
     char *sdp = 0;
     pc->GetRemoteDescription(&sdp);
     if (!sdp) {
       return "";
     }
-    return sdp;
+    std::string result(sdp);
+    delete sdp;
+    return result;
   }
 
   // Adds a stream to the PeerConnection.
   void AddStream(uint32_t hint =
          DOMMediaStream::HINT_CONTENTS_AUDIO |
          DOMMediaStream::HINT_CONTENTS_VIDEO,
        MediaStream *stream = nullptr) {
 
@@ -1123,17 +1127,17 @@ class SignalingAgent {
     AddStream(aHintContents, audio_stream);
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->CreateOffer(options), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
                      kDefaultTimeout);
     ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
-    SDPSanityCheck(pObserver->lastString, sdpCheck, true);
+    SDPSanityCheck(pObserver->lastString.c_str(), sdpCheck, true);
     ASSERT_EQ(signaling_state(), endState);
     offer_ = pObserver->lastString;
   }
 
 void CreateAnswer(uint32_t offerAnswerFlags,
                     uint32_t sdpCheck = DONT_CHECK_AUDIO|
                                         DONT_CHECK_VIDEO|
                                         DONT_CHECK_DATA,
@@ -1151,17 +1155,17 @@ void CreateAnswer(uint32_t offerAnswerFl
 
     // Decide if streams are disabled for offer or answer
     // then perform SDP checking based on which stream disabled
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->CreateAnswer(), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
                      kDefaultTimeout);
     ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
-    SDPSanityCheck(pObserver->lastString, sdpCheck, false);
+    SDPSanityCheck(pObserver->lastString.c_str(), sdpCheck, false);
     ASSERT_EQ(signaling_state(), endState);
 
     answer_ = pObserver->lastString;
   }
 
   // At present, we use the hints field in a stream to find and
   // remove it. This only works if the specified hints flags are
   // unique among all streams in the PeerConnection. This is not
@@ -1179,17 +1183,17 @@ void CreateAnswer(uint32_t offerAnswerFl
     RemoveLastStreamAdded();
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->CreateOffer(options), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
                      kDefaultTimeout);
     ASSERT_TRUE(pObserver->state == TestObserver::stateSuccess);
-    SDPSanityCheck(pObserver->lastString, sdpCheck, true);
+    SDPSanityCheck(pObserver->lastString.c_str(), sdpCheck, true);
     offer_ = pObserver->lastString;
   }
 
   void SetRemote(TestObserver::Action action, std::string remote,
                  bool ignoreError = false,
                  PCImplSignalingState endState =
                    PCImplSignalingState::SignalingInvalid) {
 
@@ -1420,18 +1424,18 @@ void CreateAnswer(uint32_t offerAnswerFl
                   video_conduit->UsingNackBasic());
         ASSERT_EQ(frameRequestMethod, video_conduit->FrameRequestMethod());
     }
   }
 
 public:
   nsRefPtr<PCDispatchWrapper> pc;
   nsRefPtr<TestObserver> pObserver;
-  char* offer_;
-  char* answer_;
+  std::string offer_;
+  std::string answer_;
   nsRefPtr<DOMMediaStream> domMediaStream_;
   sipcc::IceConfiguration cfg_;
   const std::string name;
 
 private:
   void SDPSanityCheck(std::string sdp, uint32_t flags, bool offer)
   {
     ASSERT_TRUE(pObserver->state == TestObserver::stateSuccess);