注意如果想让某程序可以被gdb调试,编译的时候就必须加上 gcc 或者g++ -g 命令
live555有专门配置为gdb的配置文件!只需配置即可
liqinghan@ubuntu:~/work/live/testProgs$ gdb ./testRTSPClient
run/r argv参数 运行程序
(gdb) run rtsp://192.168.1.2:8554/11.mkv
break/b class::func(type,type,..) 设置某个类的函数断点
(gdb) break DummySink::afterGettingFrame(void*,unsigned , unsigned,struct timeval,unsigned)
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y <PENDING> DummySink::afterGettingFrame(void*,unsigned , unsigned,struct timeval,unsigned)
break func 设置函数断点
info break查看断点
watch expr当expr变化时,停止运行。
continue/c 继续执行
p 查看变量值
s 单步调试(进入函数)
n 单步调试(不进函数)
d 删除指定编号的某个断点(使用info列出的断点)
如下:
(gdb) info break
Num Type Disp Enb Address What
2 hw watchpoint keep y DummySink::afterGettingFrame(void*,unsigned,unsigned,struct timeval,unsigned)
3 breakpoint keep y <PENDING> DummySink::afterGettingFrame(void*,unsigned,unsigned,struct timeval,unsigned)
4 breakpoint keep y 0x0804954e in DummySink::continuePlaying()
at testRTSPClient.cpp:523
那么Num就是编号
break lineNum也可以,执行到当前文件的行号
break 491
9 breakpoint keep y 0x08049ff4 in DummySink::afterGettingFrame(void*, unsigned int, unsigned int, timeval, unsigned int) at testRTSPClient.cpp:491
break 500
10 breakpoint keep y 0x08049e3a in DummySink::afterGettingFrame(unsigned int, unsigned int, timeval, unsigned int) at testRTSPClient.cpp:500
bt 查看函数堆栈
finish 退出函数
typedef void (afterGettingFunc)(void* clientData, unsigned frameSize,
unsigned numTruncatedBytes,
struct timeval presentationTime,
unsigned durationInMicroseconds);
经过调试可以知道RTSPClinet的执行顺序:
1、DummySink::afterGettingFrame(void*, unsigned int, unsigned int, timeval, unsigned int)
2、DummySink::afterGettingFrame(unsigned int, unsigned int, timeval, unsigned int)
//已经得到下一帧数据,用户自己要做的事情,比如调用函数输出视频帧,以及帧信息。用户可以在启动RTSP Client的时候注册一个函数,然后在这个里面调用这个函数,输出这视频帧,即可!
3、DummySink::continuePlaying()
fSource->getNextFrame(fReceiveBuffer, DUMMY_SINK_RECEIVE_BUFFER_SIZE,
afterGettingFrame, this,
onSourceClosure, this); //获取下一帧数据
afterGettingFunc* afterGettingFunc,
void* afterGettingClientData,
onCloseFunc* onCloseFunc,
void* onCloseClientData) {
doGetNextFrame();//MultiFramedRTPSource::doGetNextFrame
}
void MultiFramedRTPSource::doGetNextFrame() {
if (!fAreDoingNetworkReads) {
// Turn on background read handling of incoming packets:
fAreDoingNetworkReads = True;
TaskScheduler::BackgroundHandlerProc* handler
= (TaskScheduler::BackgroundHandlerProc*)&networkReadHandler;
fRTPInterface.startNetworkReading(handler);
}
fSavedTo = fTo;
fSavedMaxSize = fMaxSize;
fFrameSize = 0; // for now
fNeedDelivery = True;
doGetNextFrame1();
}
void MultiFramedRTPSource::doGetNextFrame1() {
...
nextPacket->use(fTo, fMaxSize, frameSize, fNumTruncatedBytes,
fCurPacketRTPSeqNum, fCurPacketRTPTimestamp,
fPresentationTime, fCurPacketHasBeenSynchronizedUsingRTCP,
fCurPacketMarkerBit);
...
}
类继承关系如下图所示