packageRemoveSuccessHandler() 处的分段错误
segmentation fault at packageRemoveSuccessHandler()
我正在使用 M600pro 模拟器开发 DJI osdk 应用程序。
当我运行我的软件时,有时会出现分段错误
在 SubscriptionPackage::packageRemoveSuccessHandler()。
OSDK 版本为 3.6。
我想出了这个错误发生的地方。
我在 dji_subscription.cpp 中添加了 printf()s,如下所示:
void
SubscriptionPackage::packageRemoveSuccessHandler()
{
printf("SubscriptionPackage::packageRemoveSuccessHandler 1\n");
// Clean up
// Step 1. Clear fields in TopicDataBase
for (size_t i = 0; i < info.numberOfTopics; ++i)
{
printf("SubscriptionPackage::packageRemoveSuccessHandler 2(i:%d)\n",i);
printf("sizeof topicList = %d\n",sizeof(topicList));
printf("sizeof TopicDataBase = %d\n",sizeof(TopicDataBase));
printf("topicList[i] = %d\n",topicList[i]);
TopicDataBase[topicList[i]].freq = 0; // <<<< SEGMENTATION FAULT OCCURS AT HERE
printf("SubscriptionPackage::packageRemoveSuccessHandler 3\n");
TopicDataBase[topicList[i]].pkgID = 255; // Set pkgID to invalid
printf("SubscriptionPackage::packageRemoveSuccessHandler 4\n");
TopicDataBase[topicList[i]].latest = NULL; // Clear data pointer
printf("SubscriptionPackage::packageRemoveSuccessHandler 5\n");
}
printf("SubscriptionPackage::packageRemoveSuccessHandler 6\n");
// Step 2. Clean up package content, except packageID
cleanUpPackage();
printf("SubscriptionPackage::packageRemoveSuccessHandler 7\n");
setOccupied(false);
printf("SubscriptionPackage::packageRemoveSuccessHandler 8\n");
}
发生段错误时,标准输出如下:
STATUS/1 @ removePackage, L466: Remove package 1 successful.SubscriptionPackage::packageRemoveSuccessHandler 1
SubscriptionPackage::packageRemoveSuccessHandler 2(i:0)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 104
SubscriptionPackage::packageRemoveSuccessHandler 3
SubscriptionPackage::packageRemoveSuccessHandler 4
SubscriptionPackage::packageRemoveSuccessHandler 5
SubscriptionPackage::packageRemoveSuccessHandler 2(i:1)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 64
SubscriptionPackage::packageRemoveSuccessHandler 3
SubscriptionPackage::packageRemoveSuccessHandler 4
SubscriptionPackage::packageRemoveSuccessHandler 5
SubscriptionPackage::packageRemoveSuccessHandler 2(i:2)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 14290160
Segmentation fault
是这个sdk的问题吗?还是我的错?
不清楚 TopicDataBase
包含什么,或者它的大小是多少,但是 14290160 几乎可以肯定不是其中的有效索引:
TopicDataBase[topicList[i]].freq = 0; // topicList[i] is 14290160
使用 gdb,我触发了分段错误并成功打印了 topicList 的内容,如下所示:
SubscriptionPackage::packageRemoveSuccessHandler 3
SubscriptionPackage::packageRemoveSuccessHandler 4
SubscriptionPackage::packageRemoveSuccessHandler 5
SubscriptionPackage::packageRemoveSuccessHandler 2(i:2)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 729312
Thread 1 "djiosdk-bridge-" received signal SIGSEGV, Segmentation fault.
0x000459e4 in DJI::OSDK::SubscriptionPackage::packageRemoveSuccessHandler (
this=0xb2094)
at /home/pi/Onboard-SDK-3.6/osdk-core/api/src/dji_subscription.cpp:832
832 TopicDataBase[topicList[i]].freq = 0;
(gdb) p TopicDataBase
= 0x882b0 <DJI::OSDK::Telemetry::TopicDataBase>
(gdb) p topicList[i]
= 729312
(gdb) p sizeof(topicList)
= 140
(gdb) p i
= 2
(gdb) p topicList
= {DJI::OSDK::Telemetry::TOPIC_HARD_SYNC, 40, 729312, 1601594222,
1717985635, 1866673765, 1819244142, 1869182069, 1918980206, 1952804193, 144,
64, 729216, DJI::OSDK::Telemetry::TOPIC_QUATERNION, 837,
DJI::OSDK::Telemetry::TOPIC_QUATERNION, 729496, 1995883856, 729528,
1995883856, 1995883856, DJI::OSDK::Telemetry::TOPIC_QUATERNION, 144,
DJI::OSDK::Telemetry::TOPIC_QUATERNION,
DJI::OSDK::Telemetry::TOPIC_ACCELERATION_GROUND,
DJI::OSDK::Telemetry::TOPIC_GPS_FUSED,
DJI::OSDK::Telemetry::TOPIC_QUATERNION, 62513, 728448, 1977251780,
DJI::OSDK::Telemetry::TOPIC_QUATERNION,
DJI::OSDK::Telemetry::TOPIC_QUATERNION, 28001,
DJI::OSDK::Telemetry::TOPIC_QUATERNION,
DJI::OSDK::Telemetry::TOPIC_QUATERNION}
(gdb)
我正在尝试使用此代码订阅:
// Subscribe Begin
bool Util::BeginSubscribe( int responseTimeout)
{
int pkgIndex;
int freq;
int numTopic;
bool enableTimestamp;
bool pkgStatus;
// ①Quaternion at 200 Hz
// ②Altitude from Valometer 200Hz
// Telemetry: Verify the subscription
ACK::ErrorCode subscribeStatus;
subscribeStatus = gVehicle->subscribe->verify(responseTimeout);
if (ACK::getError(subscribeStatus) != ACK::SUCCESS)
{
ACK::getErrorCodeMessage(subscribeStatus, __func__);
return false;
}
// Subscribe to Quaternion at freq 200 Hz.
pkgIndex = SUBSCRIBE_PACKAGE_INDEX_200Hz;
freq = 200;
TopicName topicList200Hz[] = { TOPIC_QUATERNION,TOPIC_ALTITUDE_BAROMETER };
numTopic = sizeof(topicList200Hz) / sizeof(topicList200Hz[0]);
enableTimestamp = false;
pkgStatus = gVehicle->subscribe->initPackageFromTopicList(
pkgIndex, numTopic, topicList200Hz, enableTimestamp, freq);
if (!(pkgStatus))
{
return pkgStatus;
}
subscribeStatus = gVehicle->subscribe->startPackage(pkgIndex, responseTimeout);
if (ACK::getError(subscribeStatus) != ACK::SUCCESS)
{
ACK::getErrorCodeMessage(subscribeStatus, __func__);
// Cleanup before return
gVehicle->subscribe->removePackage(pkgIndex, responseTimeout);
return false;
}
return true;
}
我自己解决了。
这发生在我用 Ctrl+C 杀死程序后重新运行我的程序时。
所以我让我的程序捕获 SIGINT 信号,然后显式调用 removePackage()
(如下所示)
vehicle->subscribe->removePackage(SUBSCRIBE_PACKAGE_INDEX_200Hz, responseTimeout);
我正在使用 M600pro 模拟器开发 DJI osdk 应用程序。
当我运行我的软件时,有时会出现分段错误 在 SubscriptionPackage::packageRemoveSuccessHandler()。
OSDK 版本为 3.6。
我想出了这个错误发生的地方。
我在 dji_subscription.cpp 中添加了 printf()s,如下所示:
void
SubscriptionPackage::packageRemoveSuccessHandler()
{
printf("SubscriptionPackage::packageRemoveSuccessHandler 1\n");
// Clean up
// Step 1. Clear fields in TopicDataBase
for (size_t i = 0; i < info.numberOfTopics; ++i)
{
printf("SubscriptionPackage::packageRemoveSuccessHandler 2(i:%d)\n",i);
printf("sizeof topicList = %d\n",sizeof(topicList));
printf("sizeof TopicDataBase = %d\n",sizeof(TopicDataBase));
printf("topicList[i] = %d\n",topicList[i]);
TopicDataBase[topicList[i]].freq = 0; // <<<< SEGMENTATION FAULT OCCURS AT HERE
printf("SubscriptionPackage::packageRemoveSuccessHandler 3\n");
TopicDataBase[topicList[i]].pkgID = 255; // Set pkgID to invalid
printf("SubscriptionPackage::packageRemoveSuccessHandler 4\n");
TopicDataBase[topicList[i]].latest = NULL; // Clear data pointer
printf("SubscriptionPackage::packageRemoveSuccessHandler 5\n");
}
printf("SubscriptionPackage::packageRemoveSuccessHandler 6\n");
// Step 2. Clean up package content, except packageID
cleanUpPackage();
printf("SubscriptionPackage::packageRemoveSuccessHandler 7\n");
setOccupied(false);
printf("SubscriptionPackage::packageRemoveSuccessHandler 8\n");
}
发生段错误时,标准输出如下:
STATUS/1 @ removePackage, L466: Remove package 1 successful.SubscriptionPackage::packageRemoveSuccessHandler 1
SubscriptionPackage::packageRemoveSuccessHandler 2(i:0)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 104
SubscriptionPackage::packageRemoveSuccessHandler 3
SubscriptionPackage::packageRemoveSuccessHandler 4
SubscriptionPackage::packageRemoveSuccessHandler 5
SubscriptionPackage::packageRemoveSuccessHandler 2(i:1)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 64
SubscriptionPackage::packageRemoveSuccessHandler 3
SubscriptionPackage::packageRemoveSuccessHandler 4
SubscriptionPackage::packageRemoveSuccessHandler 5
SubscriptionPackage::packageRemoveSuccessHandler 2(i:2)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 14290160
Segmentation fault
是这个sdk的问题吗?还是我的错?
不清楚 TopicDataBase
包含什么,或者它的大小是多少,但是 14290160 几乎可以肯定不是其中的有效索引:
TopicDataBase[topicList[i]].freq = 0; // topicList[i] is 14290160
使用 gdb,我触发了分段错误并成功打印了 topicList 的内容,如下所示:
SubscriptionPackage::packageRemoveSuccessHandler 3
SubscriptionPackage::packageRemoveSuccessHandler 4
SubscriptionPackage::packageRemoveSuccessHandler 5
SubscriptionPackage::packageRemoveSuccessHandler 2(i:2)
sizeof topicList = 140
sizeof TopicDataBase = 735
topicList[i] = 729312
Thread 1 "djiosdk-bridge-" received signal SIGSEGV, Segmentation fault.
0x000459e4 in DJI::OSDK::SubscriptionPackage::packageRemoveSuccessHandler (
this=0xb2094)
at /home/pi/Onboard-SDK-3.6/osdk-core/api/src/dji_subscription.cpp:832
832 TopicDataBase[topicList[i]].freq = 0;
(gdb) p TopicDataBase
= 0x882b0 <DJI::OSDK::Telemetry::TopicDataBase>
(gdb) p topicList[i]
= 729312
(gdb) p sizeof(topicList)
= 140
(gdb) p i
= 2
(gdb) p topicList
= {DJI::OSDK::Telemetry::TOPIC_HARD_SYNC, 40, 729312, 1601594222,
1717985635, 1866673765, 1819244142, 1869182069, 1918980206, 1952804193, 144,
64, 729216, DJI::OSDK::Telemetry::TOPIC_QUATERNION, 837,
DJI::OSDK::Telemetry::TOPIC_QUATERNION, 729496, 1995883856, 729528,
1995883856, 1995883856, DJI::OSDK::Telemetry::TOPIC_QUATERNION, 144,
DJI::OSDK::Telemetry::TOPIC_QUATERNION,
DJI::OSDK::Telemetry::TOPIC_ACCELERATION_GROUND,
DJI::OSDK::Telemetry::TOPIC_GPS_FUSED,
DJI::OSDK::Telemetry::TOPIC_QUATERNION, 62513, 728448, 1977251780,
DJI::OSDK::Telemetry::TOPIC_QUATERNION,
DJI::OSDK::Telemetry::TOPIC_QUATERNION, 28001,
DJI::OSDK::Telemetry::TOPIC_QUATERNION,
DJI::OSDK::Telemetry::TOPIC_QUATERNION}
(gdb)
我正在尝试使用此代码订阅:
// Subscribe Begin
bool Util::BeginSubscribe( int responseTimeout)
{
int pkgIndex;
int freq;
int numTopic;
bool enableTimestamp;
bool pkgStatus;
// ①Quaternion at 200 Hz
// ②Altitude from Valometer 200Hz
// Telemetry: Verify the subscription
ACK::ErrorCode subscribeStatus;
subscribeStatus = gVehicle->subscribe->verify(responseTimeout);
if (ACK::getError(subscribeStatus) != ACK::SUCCESS)
{
ACK::getErrorCodeMessage(subscribeStatus, __func__);
return false;
}
// Subscribe to Quaternion at freq 200 Hz.
pkgIndex = SUBSCRIBE_PACKAGE_INDEX_200Hz;
freq = 200;
TopicName topicList200Hz[] = { TOPIC_QUATERNION,TOPIC_ALTITUDE_BAROMETER };
numTopic = sizeof(topicList200Hz) / sizeof(topicList200Hz[0]);
enableTimestamp = false;
pkgStatus = gVehicle->subscribe->initPackageFromTopicList(
pkgIndex, numTopic, topicList200Hz, enableTimestamp, freq);
if (!(pkgStatus))
{
return pkgStatus;
}
subscribeStatus = gVehicle->subscribe->startPackage(pkgIndex, responseTimeout);
if (ACK::getError(subscribeStatus) != ACK::SUCCESS)
{
ACK::getErrorCodeMessage(subscribeStatus, __func__);
// Cleanup before return
gVehicle->subscribe->removePackage(pkgIndex, responseTimeout);
return false;
}
return true;
}
我自己解决了。
这发生在我用 Ctrl+C 杀死程序后重新运行我的程序时。
所以我让我的程序捕获 SIGINT 信号,然后显式调用 removePackage()
(如下所示)
vehicle->subscribe->removePackage(SUBSCRIBE_PACKAGE_INDEX_200Hz, responseTimeout);