linux-core分析 : sip变量赋值-指针悬挂

core调用栈

Thread 1 (Thread 0x5c8c9460 (LWP 3562)):
#0  0x4182e8e8 in raise () from /lib/libc.so.6
#1  0x4183271c in abort () from /lib/libc.so.6
#2  0x4186573c in __libc_message () from /lib/libc.so.6
#3  0x4186ff04 in malloc_printerr () from /lib/libc.so.6
#4  0x0011f7d4 in sdp_connection_free ()
#5  0x0010503c in osip_list_special_free ()
#6  0x0011fc6c in sdp_media_free ()
#7  0x0010503c in osip_list_special_free ()
#8  0x00124d74 in sdp_message_free ()
#9  0x000e6634 in SipMessageTranslate (sip=0xaca7100, OutBoundAddress=0x5c8c8a3c "", OutBoundPort=0x5c8c8bb0, bEnableRouteNewMsg=1,
    pLocalSipUsedEthIp=0x5c8c8abc "", ulLocalSipUsedEthPort=0x5c8c8bac, workerid=1) at SipRouteManager.cpp:4973
#10 0x000d815c in SynwaySipEventCallback (pEvent=0x208d178, flag=5) at SipRouteManager.cpp:1143
#11 0x402f8838 in ProcessSipEventRoute (workerid=1) at SipLogical.cpp:2691
#12 0x402dad6c in SipEventHandleThreadFR (lpParam=0x41403a1c <thread_param+4>) at SipInterface.cpp:1619
#13 0x4003ee64 in start_thread () from /lib/libpthread.so.0
#14 0x418cd588 in ?? () from /lib/libc.so.6

core分析

sdp_message_free内存释放存在问题,分析代码中sdp消息修改的内容

sdp_connection_t* audio_con = static_cast<sdp_connection_t*>(osip_list_get(&med->c_connections, 0));
	if (audio_con != NULL)
	{
		if (audio_con->c_addr != NULL)
        {
            osip_free(audio_con->c_addr);
        }
		audio_con->c_addr = c_addr;
	}

原因
直接让 audio_con->c_addr 指向 c_addr 所指向的内存,那么多个 sdp_connection_t 结构体可能会共享同一块内存。一旦原始的 c_addr 指向的内存被修改或者释放,所有指向该内存的 audio_con->c_addr 都会受到影响,导致指针悬挂

修改

使用 osip_strdup 进行复制,每个 sdp_connection_t 结构体中的 c_addr 都有自己独立的内存副本。这样,每个结构体中的地址信息可以独立修改和管理,不会相互影响

char* osip_strdup(const char *ch)
{
	char *copy = NULL;
	size_t length;
	
	if (ch == NULL)
		return NULL;
	
	length = strlen (ch);
	
	copy = (char*)osip_malloc(length + 1);
	
	osip_strncpy(copy, ch, length);
	
	return copy;
}

if (audio_con != NULL)
	{
		if (audio_con->c_addr != NULL)
        {
            osip_free(audio_con->c_addr);
			audio_con->c_addr = NULL;
        }
		char* new_addr = osip_strdup(c_addr);
        if (new_addr != NULL)
        {
            audio_con->c_addr = new_addr;
        }
	}
//#include <stdio.h> //#include <string.h> //#include <stdint.h> //#include <stdlib.h> //#include <fcntl.h> //#include <unistd.h> #include "globaldata.h" #include "mainwindow.h" #include "mainform.h" #include "udptask.h" #include "tcptask.h" #include "modbustcpserver.h" #include "modbustcpclient.h" #include "sqlitetask.h" #include "serialtask.h" #include "gpiotask.h" #include "sipmanager.h" #include "ipc_client.h" #include <QSysInfo> #include <QApplication> #include <QStringConverter> // 编码/解码工具基类 #include <QStringDecoder> // 解码器(字节流 → QString) #include <QStringEncoder> // 编码器(QString → 字节流) //#include <QQmlApplicationEngine> #include <QPixmap> #include <QSplashScreen> #include <QString> #include <QDebug> #include <QStyleFactory> #include <QSurfaceFormat> #include <QMediaDevices> #include <QAudioDevice> #include <pjsua2.hpp> //void em_sha256_cal(char *contenx, char *sha256_result); //git测试成功 int main(int argc, char *argv[]) { qDebug() << "\n********* App Start ************"; qDebug() << "运行时Qt版本:" << qVersion(); qDebug() << "编译时Qt版本:" << QT_VERSION_STR; // 应输出相同的大版本号(主版本前两位) Q_ASSERT(QT_VERSION_MAJOR == 6); // 添加设备检测代码 qDebug() << "===== 系统环境检测 ====="; QProcess permissionCheck; permissionCheck.start("sh", QStringList() << "-c" << "echo $USER"); permissionCheck.waitForFinished(); pj::VidDevManager &vidMgr = m_endpoint->vidDevManager(); unsigned devCount = vidMgr.getDevCount(); qDebug() << "===== 多媒体设备检测 ====="; qDebug() << "音频输入设备数量:" << QMediaDevices::audioInputs().count(); qDebug() << "音频输出设备数量:" << QMediaDevices::audioOutputs().count(); qDebug() << "视频输入设备数量(media):" << QMediaDevices::videoInputs().count(); qDebug() << "视频输入设备数量(pj):" << devCount; // 通过设备数量判断支持状态 qDebug() << "音频输入支持:" << (QMediaDevices::audioInputs().empty() ? "否" : "是"); qDebug() << "音频输出支持:" << (QMediaDevices::audioOutputs().empty() ? "否" : "是"); qDebug() << "视频输入支持:" << (QMediaDevices::videoInputs().empty() ? "否" : "是"); // 检查默认设备 QAudioDevice defaultInput = QMediaDevices::defaultAudioInput(); QAudioDevice defaultOutput = QMediaDevices::defaultAudioOutput(); qDebug() << "默认输入设备是否有效:" << !defaultInput.isNull(); qDebug() << "默认输出设备是否有效:" << !defaultOutput.isNull(); // 详细列出所有输入设备信息 qDebug() << "\n输入设备列表:"; for (const QAudioDevice &device : QMediaDevices::audioInputs()) { qDebug() << " - 设备名称:" << device.description(); qDebug() << " 设备ID:" << device.id(); } // 详细列出所有输出设备信息 qDebug() << "\n输出设备列表:"; for (const QAudioDevice &device : QMediaDevices::audioOutputs()) { qDebug() << " - 设备名称:" << device.description(); qDebug() << " 设备ID:" << device.id(); } QProcess groupsCheck; groupsCheck.start("groups", QStringList() << QProcessEnvironment::systemEnvironment().value("USER")); groupsCheck.waitForFinished(); QString groupOutput = groupsCheck.readAllStandardOutput(); qDebug() << "当前用户组:" << groupOutput; qDebug() << "音频设备访问权限:" << (groupOutput.contains("audio") ? "有权限" : "无权限"); QProcess pulseCheck; pulseCheck.start("pactl", QStringList() << "list"); if(!pulseCheck.waitForFinished()) { qCritical() << "PulseAudio服务异常,错误码:" << pulseCheck.errorString(); } else { qDebug() << "PulseAudio服务状态: 运行正常"; } //qputenv("QT_OPENGL", "desktop"); // 或者 "es2" 针对嵌入式平台 //qputenv("QT_SCRN_INTEGRATION", "eglfs"); // 适用于嵌入式设备 // 设置OpenGL全局格式 // QSurfaceFormat format; // format.setRenderableType(QSurfaceFormat::OpenGL); // format.setProfile(QSurfaceFormat::CoreProfile); //format.setVersion(3, 3); //QSurfaceFormat::setDefaultFormat(format); qputenv("QT_IM_MODULE", QByteArray("tgtsml")); //设置环境变量 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QApplication::setHighDpiScaleFactorRoundingPolicy( Qt::HighDpiScaleFactorRoundingPolicy::PassThrough ); // char sha256_ctx[50], sha256_result[64]; // FILE *fp; // memset(sha256_ctx, 0, sizeof(sha256_ctx)); // memset(sha256_result, 0, sizeof(sha256_result)); // /* 给用于HAS-256计算的常量赋值,这里是公司名称,主板名称加上日期,用于可自定义内容 */ // sprintf(sha256_ctx, "Emtronix ESM8000 2021-11-18"); // /* 进行HAS-256计算 */ // em_sha256_cal(sha256_ctx, sha256_result); // /* 将结果保存在文件中,用户可以自己定义路径以及文件名 */ // fp = fopen("/mnt/mmc/Key", "w+"); // /* 因为HSA-256的结果是以字符串形式返回,所以可以直接写入文件中 */ // fwrite(sha256_result, strlen(sha256_result) , 1, fp ); // fclose(fp); // if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling,true); QApplication::addLibraryPath("./plugins"); //Qt加载数据库时,数据库驱动必须放在sqldrivers文件夹下;将Qt安装程序的plugins/sqldrivers路径复制到EXE文件同根目录下 QApplication a(argc, argv); a.setFont(QFont("Microsoft YaHei", 9)); QString platformName = QSysInfo::productType(); // 获取平台名称 qDebug() << "Platform Name:" << platformName; GlobalData::platformName = platformName; QString kernelVersion = QSysInfo::kernelVersion(); // 获取内核版本 qDebug() << "Kernel Version:" << kernelVersion; a.setStyle(QStyleFactory::create("Fusion")); QPalette palette; palette.setColor(QPalette::Window, QColor(53,53,53)); a.setPalette(palette); //QPixmap pixmap("://images/bg0.png"); //QSplashScreen splash(pixmap); //splash.show(); //a.processEvents(); GlobalData GData; SQLiteTask myLiteDb; IPC_Client ipc_Client; UdpTask udpTask; udpTask.StartIdle(); TcpTask tcpTask; ModbusTcpServer modbusTcpServer; //MainWindow menuWindow; //menuWindow.setWindowFlags(Qt::FramelessWindowHint); //menuWindow.hide(); MainForm mainForm; //SipManager sipManager; mainForm.setWindowFlags(Qt::FramelessWindowHint); mainForm.show(); mainForm.initform(); //splash.finish(&menuWindow); //ModbusTcpClient modbusTcpClient; //SerialTask serialTask; //GpioTask gpioTask; //QObject::connect(&menuWindow,SIGNAL(showMainForm()),&mainForm,SLOT(getShow())); //QObject::connect(&mainForm,SIGNAL(showMenuWindow()),&menuWindow,SLOT(getShow())); return a.exec(); } 我想在设备运行的时候通过pj库来检测摄像头来检验pj是否支持视频功能 但是遇到编译报错/home/shz/Project/appTest/appHDQt6/main.cpp:56: error: ‘m_endpoint’ was not declared in this scope ../appHDQt6/main.cpp: In function ‘int main(int, char**)’: ../appHDQt6/main.cpp:56:33: error: ‘m_endpoint’ was not declared in this scope 56 | pj::VidDevManager &vidMgr = m_endpoint->vidDevManager(); | ^~~~~~~~~~
09-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八月的雨季997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值