Re[7]: Проблема с интеграцией, компилятор "ест" память
От: Ziaw Россия  
Дата: 29.05.10 05:40
Оценка:
Здравствуйте, Маслаков Михаил, Вы писали:

ММ>Ёлки палки, я до самого низа докопал функционал доставания схемы. Повсюду кидал эксепшены, чтобы хоть какую-то дебаг информацию получать

ММ>Выходило, что при компиляции таблицы в схеме были, но тем не менее в Error List ошибка оставалась.
ММ>Так что ты прав, всё дело было в кеше интеллисенса. Есть какой-то способ его сбросить, не рестартуя студию?

Да, дело такое. Обидно, что даже рестарт студии не всегда спасает . Особенно ярко подобные артефакты вылазят при апгрейде немерла. Не постил этот баг т.к. сначала хотел понять его принцип, но так и не понял. Пока просто не доверяю ошибкам в error list, а вытаскиваю output и делаю ребилд.
Re[4]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 02.06.10 20:49
Оценка:
Здравствуйте, VladD2, Вы писали:

ММ>>Проблема судя по всему в Entity Framework, который я использую для доступа к данным (через отдельный class library проект).

ММ>>Как только я добавляю код, в котором есть доступ к данным через ObjectQuery, компилятор вешается.

Я кажется понял, в чем дело.

— В режиме интеграции компилятор загружает типы сборки не сразу, а по мере необходимости.
— Тип ObjectQuery[T] унаследован от одноименного, но не генерик типа ObjectQuery. ( class ObjectQuery<T> : ObjectQuery {} )
— Компилятор, загружая тип ObjectQuery[T] пытается обойти всех его предков.
— К моменту обработки родительского типа (ObjectQuery) компилятор уже загрузил информацию о типе ObjectQuery[T].
— Компилятор пытается найти тип ObjectQuery среди уже загруженных типов.
— На беду, поиск типа производится без учета параметров, только по имени, от которого отбрасывается символ ` и все, что расположено за ним. Если тип с подходящим именем найден и он единственный, то они и считается подходящим. (Такая логика допустима только в том случае, если к этому моменту будут загружены все типы всех сборок, а в режиме интеграции это условие не соблюдается)
— Количество параметров проверяется при поиске только в том случае, если найдено несколько одноименных типов. Более строгая проверка параметров откладывается на поздний этап. В коде по этому поводу есть коммент "incorrect number of args is reported later in a cleaner way" — это строка 377 файла NamespaceTree.n Но дело до этого более позднего этапа увы не доходит.
— Таким образом, в качестве родительского типа для ObjectQuery[T] используется информация о нем же.
— Далее компилятор натыкается в коде на конструкцию ObjectQuery[T].Where() и пытается найти объявление метода Where сначала с классе ObjectQuery[T] (безуспешно), а затем в базовом классе. А поскольку базовым считается тот же ObjectQuery[T], то компилятор уходит в бесконечный цикл, который сваливается по OutOfMemory.

Вот основной виновник торжества:

\ncc\hierarchy\NamespaceTree.n (363)

      public LookupType (split : list [string], args_count : int) : option [TypeInfo]
      {
        def search (cached) {
          | (x : TypeInfo) :: xs =>
            if (args_count == -1 || args_count == x.TyparmsCount)
              Some (x)
            else
              search (xs)
            
          | [] => None ()
        }
        
        match (TryPath (split)) {  <------- Поиск без учета args_count 
          | TypeInfoCache.Cached (tc) =>
            // incorrect number of args is reported later in a cleaner way 
            Some(tc);  <------- откладываем проверку
            
          | TypeInfoCache.NotLoaded (e) =>
            e.ConstructTypeInfo (Path (split), true);
           
            // incorrect number of args is reported later in a cleaner way 
            Some(e.tycon)  <------- откладываем проверку

          | TypeInfoCache.NotLoadedList as val =>
            def cached = Path (split).LoadValue (val);
            search (cached)
            
          | CachedAmbiguous (all) => search (all)

          | TypeInfoCache.MacroCall | TypeInfoCache.No
          | TypeInfoCache.NamespaceReference => None ()
        }
      }


Фикс я в принципе уже написал, выложу как завершу тестирование.
Юнит тест похоже тут не написать, т.к. ошибка проявляется только в режиме интеграции.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[5]: Проблема с интеграцией, компилятор "ест" память
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.06.10 21:59
Оценка:
Здравствуйте, seregaa, Вы писали:

S>Юнит тест похоже тут не написать, т.к. ошибка проявляется только в режиме интеграции.


А вот это странно. Что в интеграции такого, что меняет поведение? Тут что-то не так.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 02.06.10 22:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А вот это странно. Что в интеграции такого, что меняет поведение? Тут что-то не так.


В режиме интеграции типы из внешних сборок грузятся не все сразу, а по мере необходимости. В режиме интеграции все так и работает — я проверял под отладчиком, изначально ноды, соответствующие неймспесам пустые, и дополняются типами по ходу компиляции.

Обычную компиляцию не дебажил, прошелся по исходникам глазками — в ManagerClass.Run() вызывается LoadExternalLibraries() и дальше по цепочке, пока не вызовется LibraryReferenceManager.LoadTypesFrom(lib), в которой все типы и прогружаются.

Провел эксперимент: Взял приаттаченный проект, открыл исходник, раскомментировал строку и сразу загрузка проца и памяти поползли вверх, пока не случился OutOfMemory. Закрыл окно с исходником, и тут же в студии вызвал Rebuld All — все нормально скомпилировалось.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[7]: Проблема с интеграцией, компилятор "ест" память
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.06.10 23:40
Оценка:
Здравствуйте, seregaa, Вы писали:

S>Здравствуйте, VladD2, Вы писали:


VD>>А вот это странно. Что в интеграции такого, что меняет поведение? Тут что-то не так.


S>В режиме интеграции типы из внешних сборок грузятся не все сразу, а по мере необходимости.

S> В режиме интеграции все так и работает — я проверял под отладчиком, изначально ноды, соответствующие неймспесам пустые, и дополняются типами по ходу компиляции.

В режиме компиляции происходит тоже самое. В этом плане ничего не менялось. Разница только в том, что перезагрузку типов может происходить многократно (при изменении сборок, например).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Проблема с интеграцией, компилятор "ест" память
От: catbert  
Дата: 22.10.10 11:31
Оценка:
Здравствуйте, Маслаков Михаил, Вы писали:

ММ>Всем привет!


ММ>Решил написать Nemerle версию NerdDinner'а. В основном для себя, чтобы поближе с языком познакомиться. Если реализация будет близка к конечному результату, то можно будет и выложить для примера.


ММ>Так вот, столкнулся с проблемой — студия почему-то постоянно отжирает себе одно из 4х ядер процессора, как вовремя компиляции, так и вовремя разработки. Количество отъедаемой памяти при этом бытро растёт, пока компилятор не вываливается с OutOfMemoryException.


ММ>Что-либо делать в таких условиях реально сложно, тем более что языка то ещё толком не знаю.

ММ>Может подскажите, куда копать?

Еще один похожий случай, на этот раз с SQLite.NET: http://code.google.com/p/nemerle/issues/detail?id=1275
Re[2]: Проблема с интеграцией, компилятор "ест" память
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.10.10 14:33
Оценка:
Здравствуйте, catbert, Вы писали:

C>Еще один похожий случай, на этот раз с SQLite.NET: http://code.google.com/p/nemerle/issues/detail?id=1275


Эх. А как окружение воспроизвести?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Проблема с интеграцией, компилятор "ест" память
От: catbert  
Дата: 23.10.10 13:43
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, catbert, Вы писали:


C>>Еще один похожий случай, на этот раз с SQLite.NET: http://code.google.com/p/nemerle/issues/detail?id=1275


VD>Эх. А как окружение воспроизвести?


Ну, там проект в комментариях прикреплен.
Re[8]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 06.01.11 10:40
Оценка: 232 (3)
Здравствуйте, VladD2, Вы писали:

S>>В режиме интеграции типы из внешних сборок грузятся не все сразу, а по мере необходимости.

S>> В режиме интеграции все так и работает — я проверял под отладчиком, изначально ноды, соответствующие неймспесам пустые, и дополняются типами по ходу компиляции.

VD>В режиме компиляции происходит тоже самое. В этом плане ничего не менялось. Разница только в том, что перезагрузку типов может происходить многократно (при изменении сборок, например).


Прошелся по коду в отладке еще раз. На самом деле компилятор вылетает и в режиме интеграции и в режиме компиляции. А типы из внешних библиотек грузятся все сразу — в методе ManagerClass.LoadExternalLibraries(). Баг проявился из за того, что не все используемые библиотеки были прописаны в референсах проекта:
MvcApplication4 содержит ссылку на библиотеку NNerdDinner.Domain, классы которой унаследованы от классов Entity Framework-а (System.Data.Entity). При этом в проекте MvcApplication4 ссылка на Entity Framework отсутствует.

Компилятор C# в такой ситуации отказывается компилировать проект, требуя явно прописать ссылки на все библиотеки. А компилятор Nemerle пытается подгружать типы из неизвестных (не прописанных в reference-ах) библиотек на лету во время компиляции. И тут типы грузятся не все сразу, а только по мере необходимости. А как я уже писал выше, алгоритм поиска типов в сборках написан в предположении, что все типы сборки уже загружены, поэтому здесь поиск лажает и классу ObjectQuery<T> в качестве базового прописывается этот же ObjectQuery<T> (вместо ObjectQuery). Эта циклическая ссылка и вызывает переполнение памяти.

Есть два варианта исправления:

— аналогично компилятору c# отказываться компилировать проект с отсутствующими сылками

— исправить логику поиска типа в сборке. (это метод LookupType класса NamespaceTree). И возможно придется допиливать не только это метод. Код работы с типам вызывает ощущение того, что он писался в до-генериковую эпоху, и поддержка генериков была прикручена позже и как видно не совсем корректно.

Какой вариант выбираем?

p.s. минимальный солюшн, демонсирирующий баг, прикреплен к описанию дефект на гуглкоде http://code.google.com/p/nemerle/issues/detail?id=1230 . Солюшн самодостаточен, независим от Entity Framework или других внешних библиотек.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[9]: Проблема с интеграцией, компилятор "ест" память
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.01.11 13:37
Оценка:
Здравствуйте, seregaa, Вы писали:

S>Есть два варианта исправления:


S>- аналогично компилятору c# отказываться компилировать проект с отсутствующими сылками


S>- исправить логику поиска типа в сборке. (это метод LookupType класса NamespaceTree). И возможно придется допиливать не только это метод. Код работы с типам вызывает ощущение того, что он писался в до-генериковую эпоху, и поддержка генериков была прикручена позже и как видно не совсем корректно.


S>Какой вариант выбираем?


Тот что проще в реализации, т.е. видимо первый.

S>p.s. минимальный солюшн, демонсирирующий баг, прикреплен к описанию дефект на гуглкоде http://code.google.com/p/nemerle/issues/detail?id=1230 . Солюшн самодостаточен, независим от Entity Framework или других внешних библиотек.


Может сам попробуешь исправить? Если не выйдет, я завтра постараюсь поправить (сегодня голова не варит).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 06.01.11 13:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Может сам попробуешь исправить? Если не выйдет, я завтра постараюсь поправить (сегодня голова не варит).

ok, попробую.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[10]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 06.01.11 21:11
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Может сам попробуешь исправить? Если не выйдет, я завтра постараюсь поправить (сегодня голова не варит).


А как правильнее вывести сообщение об ошибке и прервать компиляцию? Util.ice выводит очень уж страшное сообщение с припиской "please report a bug to bugs.nemerle.org. You can try modifying program near this location.", что не очень то подходит в данном случае. А Message.Error() не прерывает компиляцию.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[11]: Проблема с интеграцией, компилятор "ест" память
От: WolfHound  
Дата: 06.01.11 21:22
Оценка: +1
Здравствуйте, seregaa, Вы писали:

S>А как правильнее вывести сообщение об ошибке и прервать компиляцию? Util.ice выводит очень уж страшное сообщение с припиской "please report a bug to bugs.nemerle.org. You can try modifying program near this location.", что не очень то подходит в данном случае. А Message.Error() не прерывает компиляцию.

Может Message.FatalError?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: Проблема с интеграцией, компилятор "ест" память
От: Ziaw Россия  
Дата: 06.01.11 21:22
Оценка: +1
Здравствуйте, seregaa, Вы писали:

S>Здравствуйте, VladD2, Вы писали:


VD>>Может сам попробуешь исправить? Если не выйдет, я завтра постараюсь поправить (сегодня голова не варит).


S>А как правильнее вывести сообщение об ошибке и прервать компиляцию? Util.ice выводит очень уж страшное сообщение с припиской "please report a bug to bugs.nemerle.org. You can try modifying program near this location.", что не очень то подходит в данном случае. А Message.Error() не прерывает компиляцию.


ice это если компилятор не может дальше работать и сам не понимает почему.

Message.FatalError(), емнип прерывает компиляцию.
Re[12]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 06.01.11 21:41
Оценка:
Здравствуйте, WolfHound, Вы писали:

S>>А как правильнее вывести сообщение об ошибке и прервать компиляцию? Util.ice выводит очень уж страшное сообщение с припиской "please report a bug to bugs.nemerle.org. You can try modifying program near this location.", что не очень то подходит в данном случае. А Message.Error() не прерывает компиляцию.

WH>Может Message.FatalError?

Похоже оно )
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[12]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 06.01.11 21:45
Оценка:
Здравствуйте, Ziaw, Вы писали:

S>>А как правильнее вывести сообщение об ошибке и прервать компиляцию? Util.ice выводит очень уж страшное сообщение с припиской "please report a bug to bugs.nemerle.org. You can try modifying program near this location.", что не очень то подходит в данном случае. А Message.Error() не прерывает компиляцию.


Z>ice это если компилятор не может дальше работать и сам не понимает почему.


В моем случае причина ошибки известна, и это не внутренняя ошибка компилятора, а ошибка во внешнем файле проекта. Поэтому тут имхо ice
(internal compiler error) не очень подходит.

Z>Message.FatalError(), емнип прерывает компиляцию.

ага, точно!
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[10]: Проблема с интеграцией, компилятор "ест" память
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.01.11 15:05
Оценка:
Здравствуйте, VladD2, Вы писали:

S>>- аналогично компилятору c# отказываться компилировать проект с отсутствующими сылками


S>>- исправить логику поиска типа в сборке. (это метод LookupType класса NamespaceTree). И возможно придется допиливать не только это метод. Код работы с типам вызывает ощущение того, что он писался в до-генериковую эпоху, и поддержка генериков была прикручена позже и как видно не совсем корректно.


S>>Какой вариант выбираем?


У тебя получилось, что компилятор теперь орет не только на использование типа из сборки которая не подключена, а на то, что не подключены сборки на которые хоть как-то (даже опосредовано) ссылаются зависимые сборки. В результате компилятор орет на полную фигню. Даже если тип никогда и ни где не используется, компилятор требует явно подключить ВСЕ зависимые сборки.

Это просто ужасно! В солюшене из тройки проектов уже просто невозможно работать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 07.01.11 18:05
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>У тебя получилось, что компилятор теперь орет не только на использование типа из сборки которая не подключена, а на то, что не подключены сборки на которые хоть как-то (даже опосредовано) ссылаются зависимые сборки. В результате компилятор орет на полную фигню. Даже если тип никогда и ни где не используется, компилятор требует явно подключить ВСЕ зависимые сборки.


VD>Это просто ужасно! В солюшене из тройки проектов уже просто невозможно работать.


Приведи плиз пример. Я проверил пару сценариев и пока компилятор работает аналогично компилятору шарпа.

К примеру, создаю прокта, содержащий ссылку на System.Data.SqlServerCe и не содержащий ссылку на System.Data. В проекте создаю код, испльзующий SqlCeEngine (уникальный для этой сборки класс, не унаследованный от классов внешних сборок), код успешно компилируется и шарпом и немерле. Затем добавляю в проект код, испльзующий SqlCeCommand (унаследованный от DbCommand из неподцепленной сборки System.Data) и оба копилятора начинают ругаться на отсутствие сборки.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[12]: Проблема с интеграцией, компилятор "ест" память
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.01.11 18:36
Оценка:
Здравствуйте, seregaa, Вы писали:

S>Приведи плиз пример. Я проверил пару сценариев и пока компилятор работает аналогично компилятору шарпа.


Ситуация была такая.

Есть проект в котором делается реализация интерфейса. Сам интерфейс описан в другом проекте (но это видимо не важно).

Так вот при реализации интерфейса человек оставляет публичный метод который содержит параметр с типом из другой сборки.
Далее в другом проекте создается тип реализующий интерфейс и сразу же приводится к интервейсу. Но появляется это сообщение (плюс еще меседжбокс) и ничего не работает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Проблема с интеграцией, компилятор "ест" память
От: seregaa Ниоткуда http://blogtani.ru
Дата: 07.01.11 18:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так вот при реализации интерфейса человек оставляет публичный метод который содержит параметр с типом из другой сборки.

VD>Далее в другом проекте создается тип реализующий интерфейс и сразу же приводится к интервейсу. Но появляется это сообщение (плюс еще меседжбокс) и ничего не работает.

Попробую воспроизвести на обоих компиляторах. А вот с меседжбоксом странно — у меня он еще ни разу не выскочил.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.