我正在使用M600pro模拟器开发DJI osdk应用程序。
当我运行软件时,有时会发生分段错误 在SubscriptionPackage :: packageRemoveSuccessHandler()中。
OSDK版本为3.6。
我弄清楚了发生此错误的地方。
我在dji_subscription.cpp中添加了printf(),如下所示:
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");
}
发生分段错误时,stdout如下:
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的问题吗?还是我的错?
答案 0 :(得分:1)
我自己解决了。
这是在我用Ctrl + C终止运行后重新运行程序时发生的。
因此,我让程序捕获SIGINT信号,然后显式调用location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/www.sock;
fastcgi_read_timeout 300;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "upload_max_filesize = 190M \n post_max_size=190M \n max_execution_time = 300";
}
(如下所示)
removePackage()
答案 1 :(得分:0)
目前尚不清楚TopicDataBase
包含什么或它的大小,但是14290160几乎肯定不是有效的索引:
TopicDataBase[topicList[i]].freq = 0; // topicList[i] is 14290160
答案 2 :(得分:0)
使用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
$1 = 0x882b0 <DJI::OSDK::Telemetry::TopicDataBase>
(gdb) p topicList[i]
$2 = 729312
(gdb) p sizeof(topicList)
$3 = 140
(gdb) p i
$4 = 2
(gdb) p topicList
$5 = {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)
答案 3 :(得分:0)
我正在尝试使用以下代码:
// 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;
}