packageRemoveSuccessHandler()出现分段错误

时间:2018-08-10 12:08:20

标签: dji-sdk

我正在使用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的问题吗?还是我的错?

4 个答案:

答案 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;
}