[pjsip] Python3 Swig Threads Segmentation Fault at Lib Shutdown

Frank Haase fra.haase at googlemail.com
Wed May 21 18:30:32 EDT 2014


Hey,

I'm getting this error when I try to shutdown the lib:
00:07:25.820    pjsua_acc.c  .....sip:10 at server: unregistration success
00:07:26.810   pjsua_core.c  .Destroying...
00:07:26.810  pjsua_media.c  .Shutting down media..
00:07:27.121       pa_dev.c  ..PortAudio sound library shutting down..
00:07:27.122 sip_transactio  .Stopping transaction layer module
00:07:27.122 sip_transactio  .Stopped transaction layer module
00:07:27.122 sip_endpoint.c  .Module "mod-unsolicited-mwi" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-pjsua-options" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-pjsua-im" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-pjsua-pres" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-pjsua" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-stateful-util" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-refer" unregistered
00:07:27.122 sip_endpoint.c  .Module "mod-mwi" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-presence" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-evsub" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-invite" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-100rel" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-ua" unregistered
00:07:27.123 sip_transactio  .Transaction layer module destroyed
00:07:27.123 sip_endpoint.c  .Module "mod-tsx-layer" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-msg-print" unregistered
00:07:27.123 sip_endpoint.c  .Module "mod-pjsua-log" unregistered
00:07:27.124 sip_endpoint.c  .Endpoint 0x24d8be8 destroyed
00:07:27.124   pjsua_core.c  .PJSUA state changed: CLOSING --> NULL
00:07:27.124   pjsua_core.c  .PJSUA destroyed...
python: ../src/pjmedia/conference.c:1097: pjmedia_conf_remove_port:
Assertion `conf && port < conf->max_ports' failed.
Aborted (core dumped)

The problem in my application is that I use the Swig Python3 bindings with
the "-threads" options.
If I don't use this option simple programs run fine, but I need to have the
worker thread.
I'm also aware that there was a mailing list thread about this issue, but
as far as I remember Benny said that
their are no crashes any more if you iterate the media information of a
call in with:
for i in range(0, len(info.media)):
    mi = info.media[i]
what I do.
Does anybody have the same issue or some kind of fix?
I would highly appreciate it!


The setup I use:

Arch Linux system and Python3, building the library with:
./configure --disable-video CFLAGS="-fPIC" CXXFLAGS="-fPIC" && make dep &&
make && cd pjsip-apps/src/swig && make && make install

I changed the Makefile for the python swig bindings to use "-threads
-DSWIG_NO_EXPORT_ITERATOR_METHODS"
The program I use (sorry for th longer text):
import pjsua2 as pj
import time, threading
from PyQt4 import QtCore

class Endpoint(pj.Endpoint):

    instance = None

    def __init__(self):
        pj.Endpoint.__init__(self)
        Endpoint.instance = self

class Worker(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        Endpoint.instance.libRegisterWorkerThread("pjWorker")

class Call(pj.Call):
    def __init__(self, acc, peer_uri='', chat=None, call_id =
pj.PJSUA_INVALID_ID):
        pj.Call.__init__(self, acc, call_id)
        self.acc = acc
        self.connected = False
        self.onhold = False

    def onCallState(self, prm):
        ci = self.getInfo()
        self.connected = ci.state == pj.PJSIP_INV_STATE_CONFIRMED

    def onCallMediaState(self, prm):
        pass

    def hangup(self, statuscode):
        call_prm = pj.CallOpParam()
        call_prm.statusCode = statuscode
        super(Call, self).hangup(call_prm)


class Account(pj.Account):

    def __init__(self):
        pj.Account.__init__(self)
        self.cfg =  pj.AccountConfig()

    def onRegState(self, prm):
        pass

    def onIncomingCall(self, prm):
        c = Call(self, call_id=prm.callId)
        call_prm = pj.CallOpParam()
        call_prm.statusCode = 180
        c.answer(call_prm)
        ci = c.getInfo()
        call_prm.statusCode = 200
        c.answer(call_prm)

class SipTransportConfig:
def __init__(self, type, enabled):
 self.type = type
self.enabled = enabled
self.config = pj.TransportConfig()

class AppConfig:
def __init__(self):
self.epConfig = pj.EpConfig()
self.udp = SipTransportConfig(pj.PJSIP_TRANSPORT_UDP, True)
 self.tcp = SipTransportConfig(pj.PJSIP_TRANSPORT_TCP, True)
self.tls = SipTransportConfig(pj.PJSIP_TRANSPORT_TLS, False)
 self.accounts = []


class App(object):

    def __init__(self):
        self.ep = Endpoint()
        self.ep.libCreate()
        self.appConfig = AppConfig()

    def start(self):
        self.appConfig.epConfig.uaConfig.threadCnt = 0;
        self.appConfig.epConfig.uaConfig.mainThreadOnly = True
        self.appConfig.epConfig.uaConfig.userAgent = "pyTest-" +
self.ep.libVersion().full;
        self.ep.libInit(self.appConfig.epConfig)
        t1 = pj.TransportConfig()
        t1.port = 5060
        self.ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, t1)
        self.acc1 = Account()
        self.acc1.cfg.idUri = "sip:10 at server";
        self.acc1.cfg.regConfig.registrarUri = "sip:server";
        self.acc1.cfg.sipConfig.authCreds.push_back(
pj.AuthCredInfo("digest", "*", "10", 0, "10") );
        self.acc1.create(self.acc1.cfg)
        self.ep.libStart()

    def startWorker(self):
        self.worker = Worker()
        self.worker.start()

    def kill(self):
        self.ep.libDestroy()

    def makeCall(self):
        self.call = Call(self.acc1)
        prm = pj.CallOpParam()
        toCall = "sip:11 at server"
        self.call.makeCall(toCall, prm)

    def hangupCall(self):
        self.call.hangup(200)
        del self.call

def main():
    app = App()
    app.start()
    wait1 = input("start Worker")
    app.startWorker()
    wait2 = input("make call")
    app.makeCall()
    input("hangup")
    app.hangupCall()
    input("destroy")
    app.kill()

if __name__ == '__main__':
    main()



Thanks and Cheers
Frank
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20140522/73f35550/attachment.html>


More information about the pjsip mailing list