На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Ошибка сегментации при поиске на RU-SPE с вашего сайта

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
Ошибка сегментации при поиске на RU-SPE с вашего сайта
 
Доброго времени суток.

Ведём поиск на карте RU-SPE.map, полученной после установки из RU-SPE.sxf с местного репозитория электронных карт.
Код
    QString name = "1";
    QTextCodec* codec = QTextCodec::codecForName( "KOI8-R");
    HSELECT hsel = mapCreateMapSelectContext( m_hMap);
    if( hsel == 0) return;
    mapSelectObject( hsel, -1, 1);
    QByteArray ar = codec->fromUnicode( name);
    long condition_number = mapSelectSemanticAppend( hsel, CMEQUAL, 9, ar.data());
 ...
    mapSeekSelectObjectCount( m_hMap, hsel); - добавленная проверочная функция, на которой тоже падает аналогичным образом
    proceedSearch( hsel); - падает внутри

>>> текст функции  
void MapController::proceedSearch(HSELECT hsel)
{
    QTextCodec* codec = QTextCodec::codecForName( "KOI8-R");
    int count = 0;
    int flag = WO_FIRST;
    HOBJ hobj = mapCreateObject( m_hMap);
    HSITE currentSite;
    int subMapCounter = -1;
    while( !m_forceBreakSearch)
    {
        bool res;
        if( subMapCounter == -1)
        {
            res = mapSeekSelectObject( m_hMap, hobj, hsel, flag); - падает на третьем проходе после двух найденных объектов
        }
        else
        {
            res = mapSeekSiteSelectObject( m_hMap, currentSite, hobj, hsel, flag);
        }
        if( !res)
        {
            if( m_searchOnlyCentralMap)
                break;
            mapClearObject( hobj);
            subMapCounter++;
            if( subMapCounter < mapGetSiteCount( m_hMap))
            {
                currentSite = mapGetSiteIdent( m_hMap, subMapCounter + 1);
                flag = WO_FIRST;
                continue;
            }
            break;
        }
        flag = WO_NEXT;
        DFRAME dfr_obj;
        mapObjectViewFrame( hobj, &dfr_obj);
        double latx = 0, lonx = 0;
        plane2Geo( ( dfr_obj.X1 + dfr_obj.X2) / 2, ( dfr_obj.Y1 + dfr_obj.Y2) / 2, latx, lonx);
        QString name = codec->toUnicode( mapObjectName( hobj));
        MapObjInfo moi;
        moi.m_objName = name;
        moi.m_lat = latx;
        moi.m_lon = lonx;
        moi.m_index = mapGetObjectNumber(hobj);
        moi.m_hSiteIndex = subMapCounter;
        moi.m_code = mapObjectExcode(hobj);
        m_searchList.append( moi);
        if( m_searchList.size() >= 1001) break;//magic number as in MapSearchMenu, bad search request
        count++;
    }
    mapFreeObject( hobj);
}


На вызове любой из функций ТОЛЬКО на этой карте
mapSeekSelectObject
mapSeekSelectObjectCount

получаем падение с ошибкой сегментации. В отладчике стек:
0    _wtof(wchar_t const *)            0x7ffff4369a2c    
1    TMapControl::ShowMapToRst(int, DFRAME&, TPaintControl&)            0x7ffff4250020    

Как можно с данной ситуацией разобраться и что бы вы порекомендовали?

Спасибо.
С уважением,
Лазарев Александр.
Изменено: Александр Лазарев - 21.02.2018 14:25:15
 
У меня была похожая проблема с падением, на старой версии ГИСКонструктор, и тоже на одной конкретной карте, на новой разработчики не смогли воспроизвести.
И тоже вроде падало на каком-то проходе.
Лечил изменением CMEQUAL с точного названия на *паттерн* и паттерн* (содержит/начинается с)

Если пользователь ввёл, допустим,
Код
Псков
, то я искал
Код
 "ПСКОВ*"
или
Код
"*ПСКОВ*"
в зависимости от выбранного пользователя метода поиска (начинается с/содержит)
 
В новой версии 12.3.0 под Астра Линукс данная проблема с поиском на данной карте не проявляется
 
Цитата
Владимир Егоров написал:
Лечил изменением CMEQUAL с точного названия на *паттерн* и паттерн* (содержит/начинается с)
Столкнулся с аналогичной проблемой при использовании старого ГИС-Конструктора на OSM-карте Воронежской области, скачанной с сайта КБ "Панорама".
Помог ваш совет. Единственное, что после поиска и нахождения 1 или нескольких объектов вызов функции mapFreeObject() приводит к аварийному завершению приложения. Не сталкивался с этим кто-нибудь?
 
Да вроде не падало ничего. Речь про 11-ую версию?

Посмотрел старые исходники, функция поиска такая:

Код
gisserver::search::ResultList
gisserver::search::Context::search(const QString &query)
{
    if (!isValid()){
        return {};
    }
    setQuery(query);
    ResultList results;
    long ret = mapSeekSelectObject(_map, _info, _select, WO_FIRST );
    while (ret != 0){
        results << getCurrentResult();
        ret = mapSeekSelectObject(_map, _info, _select, WO_NEXT );
    }
    return results;
}
Весь cpp файл: Ссылка на Ubuntu Pastebin
 
Цитата
Владимир Егоров написал:
Да вроде не падало ничего. Речь про 11-ую версию?
Да, про 11-ю. Вроде по коду все сделано аналогично.
 
Здравствуйте!

Цитата
Сергей написал:
Единственное, что после поиска и нахождения 1 или нескольких объектов вызов функции mapFreeObject() приводит к аварийному завершению приложения. Не сталкивался с этим кто-нибудь?
Не могли бы Вы прислать маленький автономный пример поиска, чтобы мы могли проанализировать текст программы?
 
Цитата
Александр Савелов написал:
Здравствуйте!

Цитата
Сергей написал:
Единственное, что после поиска и нахождения 1 или нескольких объектов вызов функции mapFreeObject() приводит к аварийному завершению приложения. Не сталкивался с этим кто-нибудь?
Не могли бы Вы прислать маленький автономный пример поиска, чтобы мы могли проанализировать текст программы?
Да, конечно.
Код
// PanoramaUtils::ushortToWChar - преобразование ushort* в WCHAR *
// 


auto selectContext = mapCreateMapSelectContext(m_hMap); // m_hMap - хендлер открытой карты
QString searchTitle = titleName; // titleName - исходная строка для поиска как в окне ввода в "Операторе"
// костыль с поиском для указанной версии
#if ((MAPAPIVERSION == 0x111015) && (MAPACCESSVERSION == 20130912))
    
    if (!searchTitle.endsWith(QLatin1String("*")))
        searchTitle.append("*");
#endif
    mapSelectSemanticAppendUn(selectContext, CMEQUAL, 9, PanoramaUtils::ushortToWChar(searchTitle.utf16()));
    auto hObj = mapCreateObject(m_hMap);
    const auto cnt = mapSeekSelectObjectCount(m_hMap, selectContext);
    auto res = (cnt > 0) ? mapSeekSelectObject(m_hMap, hObj, selectContext, (WO_FIRST | WO_VISUALIGNORE | WO_INMAP)) : 0;
    if (res != 0) {
        do {
            
        } while (mapSeekSelectObject(m_hMap, hObj, selectContext, WO_NEXT) != 0);
    }
    
    mapDeleteObject(hObj); // если cnt > 0, то тут падает
    mapDeleteSelectContext(selectContext);
Изменено: Сергей - 17.07.2019 10:49:39
 
Код
void gisserver::search::Context::clear()
{
    DLOG(LOG_NAME, 2, "clear");
    _layers.clear();
    if (isValid()){
        mapDeleteSelectContext(_select);
        _select = 0;
        mapFreeObject(_info);
        _info = 0;
        _map = 0;
        _type = SearchType::FULL;
    }
}
Вы пытаетесь удалить объект с карты, а не освободить ресурсы.
Код
 // Удалить объект карты
 // Предыдущее состояние объекта сохраняется в резервных
 // файлах и может быть восстановлено
 // info  - идентификатор объекта карты в памяти
 // Признак удаления записывается в памяти и в файле
 // При ошибке возвращает ноль

_MAPIMP long int _MAPAPI mapDeleteObject(HOBJ info);


  // Удалить описание объекта векторной карты из памяти
  // info - идентификатор объекта карты в памяти
  // Для сохранения объекта на карте необходимо
  // до вызова mapFreeObject(...) выполнить функцию
  // mapCommitObject(...)
  // При ошибке возвращает ноль

_MAPIMP void _MAPAPI mapFreeObject(HOBJ info);

Возможно, из-за этого и происходит падение.
Изменено: Владимир Егоров - 17.07.2019 10:45:41
 
Цитата
Владимир Егоров написал:
Возможно, из-за этого и происходит падение.
Спасибо, проблема оказалась именно в этом. Необходимо использовать mapFreeObject.
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2021

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности