Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[98.80.143.34] |
|
Сообщ.
#1
,
|
|
|
Поскольку проблемы, связанные с PalmOS 5.4 не исправлены, есть смысл в заведении топика с описанием известных проблем. Проблемы связаны с новой файловой системой NVFS.
1. При удалении базы удалятся все файлы с именами, отличающимися только регистром. 2. DmDeleteRecord регулярно падает с сообщением VFSDBCache.c, Line:6761, DeleteRecord() called on invalid record Лечится шаманскими вызовами DmQueryRecord перед удалением. Ссылки по теме: http://discussion.treocentral.com/showthread.php?t=62816 |
Сообщ.
#2
,
|
|
|
на сайте http://pluggedin.palmone.com лежит статья NVFS White Paper.
|
Сообщ.
#3
,
|
|
|
Мать моя. В вышеупомянутой статье говорится, что localID базы может измениться после ее закрытия. Ну да, как и раньше это localID чанка с заголовком базы. Но теперь такие чанки выделяются только для открытых баз. Вопрос - а как, простите, алармы работают и нотификации? Или они заголовки баз, зарегистрированных в алармах не трогают?
Свежак: очередной способ избавления от баги с удалением записи http://news.palmos.com/read/messages?id=184414#184414 |
Сообщ.
#4
,
|
|
|
3. При работе с базами PIM через PalmOne datapatch (а другого легального способа и нет) - следующие глюки:
3.1 Не работает удаление записи. То есть вообще. Машинка сразу виснет. No workaround. 3.2 запуск приложения длится не менее 5 секунд, в теч. которых машинка издаёт кликающие звуки. Это было бы смешно, если бы не было так грустно. Игорь: надо все эти приколы в Wiki заносить. Ті начни, а я помогу. |
Сообщ.
#5
,
|
|
|
Это был я.
|
Сообщ.
#6
,
|
|
|
а что такое PalmOne datapatch? мне казалось, что новые базы недокументированы, только через старые можно.
|
Сообщ.
#7
,
|
|
|
Новые недокументированы, а через старые не работает :-)
Датапатч как раз эмулирует старые базы. |
Сообщ.
#8
,
|
|
|
OFF: Видимо правильно следующим КПК я беру Zaurus, а не TT5 как хотел сначало
|
Сообщ.
#9
,
|
|
|
Создаем две базы с одинаковыми именами, но с разным регистром, разным креатором или типом. Перегружаемся. Нет ни одной.
|
Сообщ.
#10
,
|
|
|
1. Если запущена моя программа (которая являеться лончером) и я делаю HotSync для установки новой версии - стабильный ресет после синхронизации. Выход - выйти из программы, а потом устанавливать новое. Скорее всего так для всех прог, которые запущены на момент синхронизации для установки ее новой версии.
2. Похоже иначе организована система фокусов. Т.е. при использовании грида POL, в котором есть филды, на них перестал устанавливаться фокус при перемещении, точнее он устанавливаеться и тут же прячеться. 3. Всем известный факт но все же: есть машинка трео600. на ней свободной памяти 12М из ее 24. Востанавливаю бекап сей машинки на трео650, где те же 24. В итоге имею 2М сободной памяти. Т.е. 10М ушло просто так. Да здравствует энергонезависемая память. 4. Ну а про то что если ваша программа не будет выгружаться в течении дня, и вы не будете выключать машинку, то если паймать резет - все данные уходят в нибытиё - замечательная фича! З.Ы.: чем дальше тем страшнее. |
Сообщ.
#11
,
|
|
|
Э, фичи от багов отделяем, даа? Сброс кэша и кластеры - это фичи. А вот хотсинк - бага. Слушай, а фокусы - это не расширения для клавиатурной навигации гадят?
|
Сообщ.
#12
,
|
|
|
Цитата igor_n @ 4. Ну а про то что если ваша программа не будет выгружаться в течении дня, и вы не будете выключать машинку, то если паймать резет - все данные уходят в нибытиё - замечательная фича! Выход один - DmSyncDatabase после изменения данных. Не фонтан, а что делать? А! Можно напрямую на hidden том писать через VFS и выкинуть DM |
Сообщ.
#13
,
|
|
|
Цитата igor_n @ Э, фичи от багов отделяем, даа? Сброс кэша и кластеры - это фичи. А вот хотсинк - бага. Слушай, а фокусы - это не расширения для клавиатурной навигации гадят? Да их фичи кроме как задокументированными багами считать и нельзя. )) Скорее всего да, т.к. даже по сравнению с трео600 выглядит оно иначе чем на трео650. Там где я поборол на трео600 фокусировку (сделал ее так как мне надо) на трео650 вылезло тоже самое что было по первости с трео600. Вобщем смахивает на то. |
Сообщ.
#14
,
|
|
|
а медитация над frmObjectFocusTake не помогает? в доке достаточно подробно описывается логика перемещения фокуса.
|
Сообщ.
#15
,
|
|
|
да честно говоря не пробывал, мне хватило других его заморочек и как от корпоративного решения на нем я отказался. остаюсь на трео600.
|
Сообщ.
#16
,
|
|
|
пара статей от Бени про специфику NVFS
http://palmos.combee.net/blog/TheNVFSFilesDmSyncDatabas.html http://palmos.combee.net/blog/TheNVFSFilesHowSyncsCanFa.html |
Сообщ.
#17
,
|
|
|
настоящая история создания NVFS
Цитата It wasn't so much that the engineers didn't understand Palm OS; they were originally trying to get NVFS into the system while modifying as little code as possible, and originally it looked like hooking into Data Manager would be less intrusive. Remember, this wasn't done as a new release of Palm OS 5, but instead as a licensee project for palmOne. By the time we discovered that this was going to be complicated and problematic, the Treo 650 and T5 were close to ship, and the follow on versions were mainly to get that code stabilized and debugged. -- Ben Combee, Senior Software Engineer, palmOne, Inc. |
Сообщ.
#18
,
|
|
|
Как вам фокус?
1) Запускаем "Tasks", создаем записи! 2) выполняем код db_id = DmFindDatabase(0, "ToDoDB"); // получаем db_id == xxxxx !!! err = DmDeleteDatabase(0, db_id); // получаем err == errNone !!! db_id = DmFindDatabase(0, "ToDoDB"); // получаем db_id == 0 !!! Вроде все правильно, не такли 3) Запускаем "Tasks" иииии.... Все записи на месте!!!!! 4) Пробаем запустить код, и получаем... db_id = DmFindDatabase(0, "ToDoDB"); // получаем db_id == 0 !!! Reset. и все на месте З.Ы. Интерестно получается, база удалена, из другого приложения уже не достать, а "Tasks" читает ее без проблем, да и еще, эта база востанавливается при ресете. +++. Обойти это можно только удалением самих записей. З.Ы.З.Ы ни каких дополнительных программ на пальме не стоит, голый Трео 650 или Тунгстен Т5 Е2 |
Сообщ.
#19
,
|
|
|
На пальмвановских машинках, начиная с TT3 (TE и проч) вместо штатных PIM программ (Datebook, Todo, Address, Memopad) стоят версии программ от P1. Они работают со своими базами, но пытаются создавать копии данных в стандартных базах.
|
Сообщ.
#20
,
|
|
|
Пример правильного NVFS-aware кода. Возможно есть способ проще, но так вернее.
Задача. Дана запись в базе. Нужно изменить ее размер и заапдейтить. Для простоты понятные ошибки не обрабатываются, дабы была видна логика/ Цитата // взять старое значение hRec = DmQueryRecord(dbP, i); pRec = MemHandleLock(hRec); // создать копию в памяти // скопировать в память старые поля фиксированной длины // ... // освободить, чтобы отработал ресайз MemHandleUnlock(hRec); // поресайзить hRec = DmResizeRecord(dbP, i, newSize); if (hRec == NULL){ // или DmGetLastError // ... // обработать и выйти. поскольку запись была взята по Query освобождать ничего не нужно } // пользовать здесь hRec не стоит, поскольку запись не была Getнута. // вот только здесь делаем Get hRec = DmGetRecord(dbP, i); // модифицируем запись pNewRec = MemHandleLock(hRec); DmWrite(pNewRec, 0, pMemRec, newSize); MemHandleUnlock(hRec); DmReleaseRecord(dbP, i, true); Почему так сложно? Потому что непонятно, насколько правильно NVFS отрабатывает DmResizeRecord для getнутой записи. Также непонятно, что делать, если Resize из-под getа обломился. Почему-то у меня работало с единственным Query и модификацией записи по хендлу в кэше без DmGetRecord (и естественно без DmReleaseRecord). Есть ли рациональные доводы за единственный Get в начале? |
Сообщ.
#21
,
|
|
|
берем базу с 3 записями определенного размера (первая запись - менее 512 байт, вторая и третья - у меня 29882 байт и 28810 байт).
берем приведенный ниже код. запускаем первый раз - нормально. запускаем 2-ой раз - на e2 и lifedrive вылетает (на t5 и машинках без nvfs всё ok). # include <PalmOS.h> UInt32 PilotMain (UInt16 cmd, void *cmdBPB, UInt16 launchFlags) { if (cmd == sysAppLaunchCmdNormalLaunch) { UInt32 buf = 0; MemHandle h2, h3; MemPtr p2, p3; LocalID id; DmOpenRef db; id = DmFindDatabase (0, "bug"); if (id==0) return (0); db = DmOpenDatabase (0, id, dmModeReadWrite); h2 = DmGetRecord (db, 1); h3 = DmGetRecord (db, 2); p2 = MemHandleLock (h2); p3 = MemHandleLock (h3); DmWrite (p2, 0, &buf, 4); DmWrite (p3, 0, &buf, 4); MemHandleUnlock (h2); MemHandleUnlock (h3); DmReleaseRecord (db, 1, true); DmReleaseRecord (db, 2, true); DmCloseDatabase (db); } return (0); } собранные prc и pdb приложены Прикреплённый файлbug.zip (2.44 Кбайт, скачиваний: 934) |
Сообщ.
#22
,
|
|
|
а на какой строчке вылетает?
|
Сообщ.
#23
,
|
|
|
кажется DmCloseDatabase. это в принципе неважно - таблица находится в неправильном состоянии уже после первого запуска программы. второй запуск просто это показывает.
кстати после перезагрузки таблица вообще пропадает из палма. похоже это связано с введенной в последних версиях nvfs sub-allocation (или как у них там это называется) - кластер в 512 байт делится на более мелкие "подкластеры" для уменьшения потерь свобоного места |
Сообщ.
#24
,
|
|
|
t650 (с последней офиц прошивкой) с третьего раза не может открыть базу. симулятор 650 пишет
vfsdbcache.c, Line:1992, FATAdjustFreeCounts() called on table that is not affected vfsdbcache.c, Line:2374, corrupt freelist in FATUpdateTable() vfsdbcache.c, Line:2393, free counts out-of-sync in FATUpdateTable() |
Сообщ.
#25
,
|
|
|
в palm-dev-forum запостишь?
|
Сообщ.
#26
,
|
|
|
ага... только подпишусь сначала
|
Сообщ.
#27
,
|
|
|
проверил на симуляторе Tungsten X - всё нормально.
это значит, что в 5.4.9 исправили? |
Сообщ.
#28
,
|
|
|
обнаружилась ещё одна проблема с nvfs.
есть e2 со старой версией программой (без dmsyncdatabase). человек неделю работал с ней, после сделал reset - в памяти оказались корректные данные, но только вот трехдневной давности. из программы не выходили, таблицы при работе н е закрываются. в документации сказано: Цитата Backup is triggered on a limited set of events: .................................. Device sleep. Whenever the device goes to sleep as a result of the normal system sleep functionality, the Data Manager iterates through all open databases and backs them up to the non-volatile store. This takes care of those databases that are opened by an application and not closed until the application exits, and those databases that are opened by background threads that are running when the system goes to sleep. палм явно неоднокартно выключался за эти трое суток - почему же изменения не попали в nvfs? |
Сообщ.
#29
,
|
|
|
я думаю, что имеется ввиду "все грязные данные сбрасываются на флешку". скорее всего до DmReleaseRecord запись не считается грязной.
такое же поведение можно наблюдать в обычном Memos. до выхода из редактирования записи она не сохранится на флешке. |
Сообщ.
#30
,
|
|
|
Цитата edo @ проверил на симуляторе Tungsten X - всё нормально. это значит, что в 5.4.9 исправили? только что проверил на lifedrive с последним апдейтом - вылетает. версия palmos - 5.4.8 |
Сообщ.
#31
,
|
|
|
вот. написал мульку. вопрос - а почему пальмовцы сами до этого не додумались?
http://palmz.in/board/index.php?showtopic=28056 |
Сообщ.
#32
,
|
|
|
о, спасибо! полезно.
ты просто пробегаешь по базам и делаешь всем syncdatabase? Добавлено Цитата igor_n @ вопрос - а почему пальмовцы сами до этого не додумались? ну так наверное как обычно - в следующем пачте сделают. у них же все так - постепенное эволюционное развитие на своих ляпах и их решений сторонними писателями. |
Сообщ.
#33
,
|
|
|
я не нашел как из арма вызвать DmSyncDatabase. Поэтому просто закрываю все базы, открытые в режиме записи.
|
Сообщ.
#34
,
|
|
|
Игорь - это что-то... Меня уже забадали вечные слёты преференсов, я их даже на карте специально держу для быстрого востановления машинки. Щас будем тестить. Сенкс.
|
Сообщ.
#35
,
|
|
|
Может кто сможет объяснить.
Проблемы с Tungsten X. Если после soft-reset (обязательное условие) выполнять вот такой код: MemHandle new_record=DmResizeRecord(db,index,record_size); if(new_record!=NULL) { new_record=DmGetRecord(db,index); UtilsDmWriteCheck(new_record,0,record,record_size); DmReleaseRecord(db,index,true); } То после нескольких итераций (например семи) происходит софт-ресет девайса при выполнении DmResizeRecord, а симулятор просто закрывается с ошибкой. Все параметры с виду в норме. И это только на TX! На других машинках с NVFS проблем не замечено. Заменяем DmResizeRecord на свою реализацию: static MemHandle PrvResizeRecord(DmOpenRef db,UInt16 index,UInt32 new_size) { MemHandle record=DmGetRecord(db,index); if(record!=NULL) if(MemHandleResize(record,new_size)!=errNone) { DmReleaseRecord(db,index,false); record=NULL; } return record; } И соответственно немного правим код: MemHandle new_record=PrvResizeRecord(db,index,record_size); if(new_record!=NULL) { UtilsDmWriteCheck(new_record,0,record,record_size); DmReleaseRecord(db,index,true); } Теперь нет проблем! Что это может быть? Где моя ошибка? Пробовал после DmResizeRecord не вызывать DmGetRecord, но это не влияет на результат. Это сообщение было перенесено сюда или объединено из темы "DmResizeRecord на TX" |
Сообщ.
#36
,
|
|
|
Ага. Мир NVFS, жестокий и беспощадный. Это баги, внесенные в 5.4.9 изменением функциональности.
Попробуй запустить свой код под дебажным симулятором с подключенным репортером, я думаю что вылезут интересные сообщения. Это сообщение было перенесено сюда или объединено из темы "DmResizeRecord на TX" |
Сообщ.
#37
,
|
|
|
Сейчас попробую. Кстати, как я говорил сам дебажный симулятор падает при выполнении DmResizeRecord.
Это сообщение было перенесено сюда или объединено из темы "DmResizeRecord на TX" |
Сообщ.
#38
,
|
|
|
Было у меня подозрение, что с resize неладно: Известные баги PalmOS 5.4 сообщение #20.
Это сообщение было перенесено сюда или объединено из темы "DmResizeRecord на TX" |
Сообщ.
#39
,
|
|
|
Reporter вообще ничего сказать не успевает
-юсртыхэю Цитата igor_n @ Было у меня подозрение, что с resize неладно: Известные баги PalmOS 5.4 сообщение #20. Я не думал, что стоит делать DmGetRecord перед DmResizeRecord. Она же (Resize) принимает в параметрах индекс записи, а не Handle. Но вот попробовал вставить - и на симуляторе все заработало! Я говорил, что для воспроизведения проблемы необходимо выполнить soft-reset. Вероятно, система не может найти запись в DbCache, и рушится. Таким образом, думаю тему можно закрыть: Либо не сипользовать DmResizeRecord, а реализовывать вручную. Либо делать DmGetRecord перед использованием DmResizeRecord. P.S. Может эту инфу добавить в "Известные баги..."? Это сообщение было перенесено сюда или объединено из темы "DmResizeRecord на TX" |
Сообщ.
#40
,
|
|
|
Интересное в камне. Выставка чудес.
В отладочных тулзах от пальмвана есть простая утилитка MemInfo. Она показывает размеры все хипов: динамического, кэша и стораджа. Что интересно: Внимание вопрос: они что, сами не знают как проще сбросить? или просто никак не сбросишь? |
Сообщ.
#41
,
|
|
|
Что за тулза, впервые слышу? Можно ли ссылочку? В PluggedIn не нашел.
Интересно, посмотреть, может хоть она работает? Потому что все мои попытки очистить кэш на 5.4.8 провалились. |
Сообщ.
#42
,
|
|
|
поищи там Palm_SDK_Utilities.zip. со ссылками сам знаешь, там плохо.
|
Сообщ.
#43
,
|
|
|
Игорь, о каком именно Palm_SDK_Utilities.zip ты говоришь?
Да, есть такой файл в Palm SG SDK (у меня версия за октябрь 2005). Внутри этого файла только три папки - FakeCamera, tipsAndTutorial, VMFontLibrary. Никаких исходиников там нет. Пример MemoryInfoдействительно присутствует в этом SDK, но там только получение информации и никаких операций с DbCache. |
Сообщ.
#44
,
|
|
|
а это такой прикол от пальмвана. они время от времени втихую апдейтят свои тулзы и документацию. так что просто скачай новую версию.
|
Сообщ.
#45
,
|
|
|
Точно, Utils они обновили, и в них есть MemoryInfo.prc
На TX освобождает кэш только по "MemFill". По "Hotsync" кэш только забивается. Пробовал Цитата через MemChunkNew- пока не получилось. Никто больше не пробовал? попытка выделения блока размером 1 << 31 байт в куче кэша |
Сообщ.
#46
,
|
|
|
MemChunkNew был в правильной куче?
|
Сообщ.
#47
,
|
|
|
Вот код. Память просто не выделяется, если запросить (1<<31). Если просить меньше максимально возможного - выделяется.
UInt32 free;UInt32 max; MemHeapFreeBytes((1|0x8000),&free,&max); DrawLong("DbCache free",(free/1024L),0); DrawLong("DbCache max",(max/1024L),10); UInt32 size=(1L<<31); MemPtr chunk=MemChunkNew((1|0x8000),size,0x1203); MemHeapFreeBytes((1|0x8000),&free,&max); DrawLong("DbCache free",(free/1024L),20); DrawLong("DbCache max",(max/1024L),30,400); if(chunk!=NULL)MemChunkFree(chunk); Возможно неверно заданы флаги для MemChunkNew (0x1203) |
Сообщ.
#48
,
|
|
|
Новый прикол NVFS на TX.
Например нам надо прочитать все базы на девайсе. Вот упрощенный код, работающий на всем кроме TX: UInt16 count=0; LocalID db_id; do{ db_id=DmGetDatabase(0,(UInt16)count); if(db_id!=NULL) ExgDBWrite(Callback,NULL,NULL,db_id,0); count++; }while(db_id!=NULL); Callback ничего не делает, просто возвращая errNone. На TX вскоре после заполнения DbCache произойдет Fatal Alert. Но стоит нам добавить вызов DmDatabaseInfo, как все замечательно работает и на TX. Вот так: UInt16 count=0; LocalID db_id; do{ db_id=DmGetDatabase(0,(UInt16)count); if(db_id!=NULL) { DmDatabaseInfo(0,db_id,NULL,&attr,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); ExgDBWrite(Callback,NULL,NULL,db_id,0); } count++; }while(db_id!=NULL); |
Сообщ.
#49
,
|
|
|
а симулятор в репортер чего-нибудь пишет?
|
Сообщ.
#50
,
|
|
|
А на симуляторе разумеется все работает.
Кстати, кто знает как на TX посмотреть последний Fatal Alert? А то, похоже, так как на Treo - алерт не показывается в сразу soft-reset. |
Сообщ.
#51
,
|
|
|
работать-то оно может и работает на симуляторе, но вполне способно писать варнинги в репортер.
утилита debug prefs из пальмвановских тулзов на TX не работает? |
Сообщ.
#52
,
|
|
|
DebugPrefs работает, спасибо за наводку. Судя по всему ошибка генерируется системой (источник fatal alert - unknown application).
А Reporter не показывает никаких интересных сообщений - все в норме на симуляторе. |
Сообщ.
#53
,
|
|
|
unknown application - это когда SysCurAppDatabase возвращает err != errNone. Например, такое бывает при обработке нотификации hapl в procedure callback.
|
Сообщ.
#54
,
|
|
|
Откопал ещё одну фишку. Если в ARM коде создать битмапку (BmpCreate) с помощью родной функции (через R9, без PACE) и вернуть указатель на неё в 68K код, то в 68K коде эта битмапка с помощью BmpDelete не убивается, возвращается ошибка sysErrParamErr, хотя функции BmpGetBits и WinDrawBitmap работают. Я, конечно, понимаю, что поля структуры BitmapType скорее всего в LE, но какого х.... работает, скажем WinDrawBitmap. А может я в чём-то туплю...
|
Сообщ.
#55
,
|
|
|
я так понимаю, что BitmapType в 68k - это теневая структура. А ты создал только оригинальную структуру. Не исключено, что некоторые 68к функции ( особенно read only) жуют оригинальные структуры, но для изменения требуют наличия двух структур.
|
Сообщ.
#56
,
|
|
|
Цитата igor_n @ но для изменения требуют наличия двух структур Всё равно не понимаю, зачем нужна теневая структура, чтобы убить битмапку, я же не меняю поля, я просто хочу освободить память |
Сообщ.
#57
,
|
|
|
PACE ожидает указатель на 68К версию, а ты ему отдаешь ARM версию. Не работает, увы. Нужно убивать там где создавал, т.е. из ARM. Знакомые грабельки
|
Сообщ.
#58
,
|
|
|
|
Сообщ.
#59
,
|
|
|
|
Сообщ.
#60
,
|
|
|
|