информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
За кого нас держат?Сетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Крупный взлом GoDaddy 
 Просроченный сертификат ломает... 
 Phrack #70/0x46 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / beginners
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
Очень актуально! 12.07.08 10:21  Число просмотров: 1631
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 12.07.08 10:23  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> То можно снять полный дамп средствами самого WinDbg
> (из пакета "Debugging Tools for Windows").
>
> Для этого там есть специальный скрипт на VB: "adplus.vbs"
> Т.е, просто создаем *.bat файл типа этого:
Не совсем понял, можно сделать дамп памяти процесса "по заказу"? Но дело в том, что это проявляется далеко не каждый раз

> ====================< Cut here <====================
> mkdir AppTrace
> call adplus -quiet -crash -pn MyApp.exe -o %cd%\AppTrace -y
> "SRV*symbols*http://msdl.microsoft.com/download/symbols;%Sy
> stemRoot%\system32\;"
> ====================< Cut here <====================
>
> Здесь:
> MyApp.exe – EXE-файл, который падает
> AppTrace – папка, в которую будут сохраняться дампы

Про полный дамп: получили (сервер аж в Омске, надо теперь вытягивать оттуда), ограничив винде память 2мя гигами
<beginners>
Синий экран при запуске программы 26.06.08 10:36  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 26.06.08 18:48  Количество правок: 3
<"чистая" ссылка> <обсуждение закрыто>
Случилась засада: самописная аппликуха при старте на W2k3 SP1, SP2 периодически (достаточно редко, раз примерно в 1000 запусков) валит венду с вердиктом:

Analyzing "C:\temp\dmptmn\MEMORY.DMP", please wait... Done.
Crash date: Wed Jun 25 16:41:38.593 2008 (GMT+3)
Stop error code: 0x8E
Process name: buh.exe
Probably caused by: win32k.sys ( win32kIsAnyCharsetDbcs+38 )

Такая штука происходит на разных машинах, конфигурация и работоспособность железа вроде как сомнения не вызывает (глюк проявляется как на физических, так и на виртуальных серверах). "Откатить" программу до версии, в которой этого не происходит не представляется возможным, т.к. глюк крайне нерегулярен и софтина постоянно изменяется группой разрабов.

Подскажите в какую сторону копать?
Последние обновления от MS установлены? 14.07.08 22:12  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
Там у них были какие-то исправления в kernel и gdi.
Взять сислог и апплог с предыдушего успешного и проблемного... 09.07.08 17:32  
Автор: lazy_anty Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
> Случилась засада: самописная аппликуха при старте на W2k3
> SP1, SP2 периодически (достаточно редко, раз примерно в
> 1000 запусков) валит венду с вердиктом:
>
> Analyzing "C:\temp\dmptmn\MEMORY.DMP", please wait... Done.
> Crash date: Wed Jun 25 16:41:38.593 2008 (GMT+3)
> Stop error code: 0x8E
> Process name: buh.exe
> Probably caused by: win32k.sys ( win32kIsAnyCharsetDbcs+38
> )
>
> Такая штука происходит на разных машинах, конфигурация и
> работоспособность железа вроде как сомнения не вызывает
> (глюк проявляется как на физических, так и на виртуальных
> серверах). "Откатить" программу до версии, в которой этого
> не происходит не представляется возможным, т.к. глюк крайне
> нерегулярен и софтина постоянно изменяется группой
> разрабов.
>
> Подскажите в какую сторону копать?
Взять сислог и апплог с предыдушего успешного и проблемного старта и сравнить.
Мне помогло сделать рукописный (не свой, с потерянной поддержкой) системный сервис зависимым от остальных сервисов, которые должны 100% должны грузиться. Оказалось, иногда медленно запускался локальный DNS, и приложение чего-то недогоняло вовремя и рушилось.
Решительно никаких отличий :( 09.07.08 18:02  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 09.07.08 18:04  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> Взять сислог и апплог с предыдушего успешного и проблемного
> старта и сравнить.
Решительно никаких отличий, более того, аппликуха явно ни в какие eventlog не пишет, кроме как падает сама (винда это корректно фиксирует). А проблема стоит очень остро - несколько раз в день (где-то 100 клиентов в среднем) умирает ТС с этой прогой на борту. А M$ отбоярилась наличием платного суппорта...
> Мне помогло сделать рукописный (не свой, с потерянной
> поддержкой) системный сервис зависимым от остальных
> сервисов, которые должны 100% должны грузиться. Оказалось,
> иногда медленно запускался локальный DNS, и приложение
> чего-то недогоняло вовремя и рушилось.
Спасибо, учту обязательно.
Поддержка в MS 27.06.08 23:43  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 27.06.08 23:46  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
На этот вопрос на микрософте ответили:
Если у вас есть подписка Technet, то в ее рамках можно открыть инцидент в поддержке, либо для начала написать в подходящую managed news group - этот сервис тоже есть в подписке.
Я ответил:
Пожалуйста подскажите, возможны ли другие варианты: technet-подписки ни у меня, ни у других людей из компании нет. Что необходимо сделать, чтобы её получить? Возможны ли другие способы инициирования проблемы?
И тишина.
Никто не может подсказать\посодействовать нубу в понимании как-таки открыть инцидент по данной проблеме?
Если еще актуально 11.07.08 22:33  
Автор: Neznaika <Alex> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
То можно снять полный дамп средствами самого WinDbg
(из пакета "Debugging Tools for Windows").

Для этого там есть специальный скрипт на VB: "adplus.vbs"
Т.е, просто создаем *.bat файл типа этого:

====================< Cut here <====================
mkdir AppTrace
call adplus -quiet -crash -pn MyApp.exe -o %cd%\AppTrace -y "SRV*symbols*http://msdl.microsoft.com/download/symbols;%SystemRoot%\system32\;"
====================< Cut here <====================

Здесь:
MyApp.exe – EXE-файл, который падает
AppTrace – папка, в которую будут сохраняться дампы

Удачи!
Очень актуально! 12.07.08 10:21  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 12.07.08 10:23  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> То можно снять полный дамп средствами самого WinDbg
> (из пакета "Debugging Tools for Windows").
>
> Для этого там есть специальный скрипт на VB: "adplus.vbs"
> Т.е, просто создаем *.bat файл типа этого:
Не совсем понял, можно сделать дамп памяти процесса "по заказу"? Но дело в том, что это проявляется далеко не каждый раз

> ====================< Cut here <====================
> mkdir AppTrace
> call adplus -quiet -crash -pn MyApp.exe -o %cd%\AppTrace -y
> "SRV*symbols*http://msdl.microsoft.com/download/symbols;%Sy
> stemRoot%\system32\;"
> ====================< Cut here <====================
>
> Здесь:
> MyApp.exe – EXE-файл, который падает
> AppTrace – папка, в которую будут сохраняться дампы

Про полный дамп: получили (сервер аж в Омске, надо теперь вытягивать оттуда), ограничив винде память 2мя гигами
Не "по заказу" - а когда реально упадет 14.07.08 16:40  
Автор: Neznaika <Alex> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
1) Запускаешь приложение
2) Запускаешь .bat файл
3) Ждешь - пока оно упадет

Потом берешь дампы, загружаешь их в WinDbg - и вперед
Отлично, получил такую фигню: 14.07.08 18:20  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 14.07.08 18:21  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
STACK_TEXT:  
f22cba54 808629c9 00000050 c0b58cba 00000000 nt!KeBugCheckEx+0x1b
f22cbaa4 808264ca 00000000 c0b58cba 00000000 nt!MmAccessFault+0x7af
f22cbaa4 bf80f653 00000000 c0b58cba 00000000 nt!KiTrap0E+0xd8
f22cbb34 bf80ebf8 bc7d8880 00000000 00000000 win32k!IsAnyCharsetDbcs+0x38
f22cbba8 bf80eb0f bc7dc890 0000003c 00000000 win32k!PFEMEMOBJ::bInit+0x8a
f22cbbec bf963186 0000003c 00000000 001e3f30 win32k!PFFMEMOBJ::bAddEntry+0x6c
f22cbc4c bf9636a9 00000051 f22cbd64 f22cbcf0 win32k!PFFMEMOBJ::bLoadDeviceFontTable+0xef
f22cbc84 bf82ba6d bc003578 bc7327f8 bc003560 win32k!DEVICE_PFTOBJ::bLoadFonts+0x8f
f22cbc98 bf84faf4 00000000 00000000 be1d15ac win32k!PDEVOBJ::bGetDeviceFonts+0x30
f22cbce8 bf84fa99 bc787018 00000003 00000000 win32k!GreEnumFontOpen+0x3b
f22cbd40 8082350b 0221069a 00000003 00000000 win32k!NtGdiEnumFontOpen+0xc8
f22cbd40 7c9385ec 0221069a 00000003 00000000 nt!KiFastCallEntry+0xf8
0012fc28 77bfb75c 77bfb747 0221069a 00000003 ntdll!KiFastSystemCallRet
0012fc50 77bfb632 0221069a 00000000 00000001 GDI32!NtGdiEnumFontOpen+0xc
0012fc88 77bff48a 0221069a 00000000 00000001 GDI32!EnumFontsInternalW+0x2c
0012fcb8 77bff420 0221069a 00000000 00000001 GDI32!EnumFontsInternalA+0x68
0012fcd8 00a0cdc3 0221069a 0012fd44 00a0c940 GDI32!EnumFontFamiliesExA+0x32
WARNING: Stack unwind information not available. Following frames may be wrong.
0012fd98 00a0cb88 0012fdac 00a0cbcc 0012fdc0 buh+0x60cdc3
0012fdc0 00425c1b 000006cb 015d1c44 00e84174 buh+0x60cb88
0012fdfc 00494c1e 0012fe10 00494c84 0012ff50 buh+0x25c1b
0012ff50 015d1c6e 0012ff70 015d1ccd 0012ff68 buh+0x94c1e
0012ff68 00405db7 0012ffb4 00405dc5 0012ff8c buh+0x11d1c6e
0012ff8c 00405e1f 00408caf 7ffde000 015d45d2 buh+0x5db7
0012ffc0 7c82f23b 00000000 00000000 7ffde000 buh+0x5e1f
0012fff0 00000000 015d45b4 00000000 78746341 kernel32!BaseProcessStart+0x23

---
KD на !analyze -v пишет:
ERROR: Symbol file could not be found. Defaulted to export symbols for buh.exe
(buh.exe - та самая программа, которая падает)
Поскольку ламер, подскажите пожалуйста, что надо сделать чтобы выражения типа buh+0x5db7 превратить во что-то осмысленное? Delphi может генерировать .map файлы...
Во-первых, молодец – что снял дамп. 14.07.08 22:34  
Автор: Neznaika <Alex> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
Во-первых, молодец – что снял дамп.
Это главное.

Во-вторых, на wasm.ru – была утилита, которая перегоняет MAP в SYM:
(http://wasm.ru/toollist.php?list=20), но она тебе и не нужна.

Как правильно сказал Сергей, “map файл - это и есть символы”.

Тебе надо просто взять *.map, для которого у тебя есть дамп и найти в нем последнюю функцию, которая далее вызывает EnumFontFamiliesEx. Для того дампа, который ты выложил – вызов идет с адреса “buh+0x60cdbe”. Т.е. в файле *.map надо найти самое близкое значение, меньшее чем 60cdbe. Это и будет функция, в которой все падает.

В-третьих. Сдается мне, что здесь - даже и без *.map файла - все понятно.
Ваша программа вызывает системную функцию EnumFontFamiliesEx. Одним из параметов EnumFontFamiliesEx является callback-функция (функция обратного вызова; т.е, программист сам эту функцию не вызывает, она вызывается системой Windows). И эта callback-функция у вас написана с ошибкой. Возможно, в ней не проверяются входные параметры. Или она не обьявлена как экпортируемая. Или она обьявлена как fastcall. Или она пишет в область памяти, которая не проинициализирована. Или еще что-нибудь.

Что надо сделать:
1) На всякий случай, я бы собрал еще несколько дампов, чтобы убедиться –
что падает именно здесь.
2) Далее, надо сказать разработчикам – что программа падает при вызове EnumFontFamiliesEx. Обычно мест, где эта функция вызывается немного, максимум два-три. Пусть самым тщательным образом проверят все эти вызовы.

Как это можно исправить:
a) Можно заменить EnumFontFamiliesEx на более простой аналог EnumFontFamilies;
b) Можно попробовать заменить callback-функцию на “пустышку”, которая ничего реально не делает;
c) В крайнем случае – можно выкинуть все вызовы к EnumFontFamiliesEx, я думаю – что в бухгалтерской программе без этой функции вполне можно обойтись.

Удачи!
В map-файле есть длиинная последовательность вида 15.07.08 10:00  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 15.07.08 10:06  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> Тебе надо просто взять *.map, для которого у тебя есть дамп
> и найти в нем последнюю функцию, которая далее вызывает
> EnumFontFamiliesEx. Для того дампа, который ты выложил –
> вызов идет с адреса “buh+0x60cdbe”. Т.е. в файле *.map надо
> найти самое близкое значение, меньшее чем 60cdbe. Это и
> будет функция, в которой все падает.
В map-файле есть длиинная последовательность вида
  Address             Publics by Name
 0001:00AC3E44       AAMake..TAAMakeForm
 0004:0000B498       AAMake.AAMakeForm
...

---
, а в конце написано Program entry point at 0002:00021748
Как соотнести “buh+0x60cdbe” с 0001:00AC3E44? Адресов порядка 60cс00 - 60ce00 в .map не нашёл...

>
> В-третьих. Сдается мне, что здесь - даже и без *.map файла
> - все понятно.
> Ваша программа вызывает системную функцию
> EnumFontFamiliesEx. Одним из параметов EnumFontFamiliesEx
> является callback-функция (функция обратного вызова; т.е,
> программист сам эту функцию не вызывает, она вызывается
> системой Windows). И эта callback-функция у вас написана с
> ошибкой. Возможно, в ней не проверяются входные параметры.
> Или она не обьявлена как экпортируемая. Или она обьявлена
> как fastcall. Или она пишет в область памяти, которая не
> проинициализирована. Или еще что-нибудь.
В программе используется всякая дрянь типа DeveloperExpress и FastReport, боюсь что им вызов EnumFont* необходим...
> Что надо сделать:
> 1) На всякий случай, я бы собрал еще несколько дампов,
> чтобы убедиться –
> что падает именно здесь.
Убедился - падает именно здесь на разном железе на Win2k3 Standart + TS
> 2) Далее, надо сказать разработчикам – что программа падает
> при вызове EnumFontFamiliesEx. Обычно мест, где эта функция
> вызывается немного, максимум два-три. Пусть самым
> тщательным образом проверят все эти вызовы.
Разработчики занимаются логикой :) и на винде не пишут, потому как "долго" и, сильно подозреваю, не умеют. Этот падёж приходится решать, так как народу на TS становится больше и глюк начинает проявляться чаще. Откатить версию до состояния "работает" возможности нет, т.к. код не очень managed + каждый божий день делается новая логика, в общем случае не совместимая с предыдущей

> Как это можно исправить:
> a) Можно заменить EnumFontFamiliesEx на более простой
> аналог EnumFontFamilies;
Честно говоря, беглый просмотр исходников компонентов показал 11 мест только в исходниках компонентов, есть ещё несколько вхождений в .dcu (delphi compiled unit, получается после компиляции модулей, то из чего потом exe линкуется - бывает что компоненты распространяются не в виде исходных текстов, а в виде таких вот dcu). Поэтому, возможно, есть смысл поставить "пустышку" немного выше...

> Удачи!
Уточнение 15.07.08 21:10  
Автор: Neznaika <Alex> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
1) Насчет map-файла, сначала идет номер секции, потом смещение.
Ты бы выложил куда-нибудь этот EXE-файл, тебе сразу скажут – что такое "buh+0x60cdbe" :)

2) Если для компонент DeveloperExpress / FastReport нет исходников,
то можно перекрыть функцию EnumFontFamiliesEx (это называется API hook).
Выложить 40 метров? Подозреваю что не будут качать :) 16.07.08 10:36  
Автор: Ustin <Ustin> Статус: Elderman
Отредактировано 16.07.08 10:39  Количество правок: 3
<"чистая" ссылка> <обсуждение закрыто>
> 1) Насчет map-файла, сначала идет номер секции, потом
> смещение.
> Ты бы выложил куда-нибудь этот EXE-файл, тебе сразу скажут
> – что такое "buh+0x60cdbe" :)
Выложить 40 метров? Подозреваю что не будут качать :)
Если нет других путей - то конечно, не вопрос...
А надо в итоге просто увидеть именованый стек вызова функций\методов в момент падения винды. А дальше попробуем "слабать кролика"
> 2) Если для компонент DeveloperExpress / FastReport нет
> исходников,
> то можно перекрыть функцию EnumFontFamiliesEx (это
> называется API hook).
Если она не будет вызываться вообще - подозреваю, что все бухи останутся без отчётов... Перекрывать её вызовом, в конечном итоге, самой себя (плаваю в вопросе, может это и не так) - есть ли смысл?
Судя по тому, что я увидел, кролика сделать будет непросто 16.07.08 23:15  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Выложить 40 метров? Подозреваю что не будут качать :)
> Если нет других путей - то конечно, не вопрос...
> А надо в итоге просто увидеть именованый стек вызова
> функций\методов в момент падения винды. А дальше попробуем
> "слабать кролика"

Мое предположение: в результате race-а что то страшное происходит с DC (причем сам по себе он остается валидным - портятся только какие то глубинные структуры) и в один прекрасный момент при попытке работы с этим DC валится win32k. Чтобы сделать кролика тебе придется более менее повторить все рейсы, которые происходят в твоей программе (причем порча на DC может наводиться каким нибудь совершенно левым кодом: как с битым хипом - кто-то попортит хип, а падает в результате какой нибудь совершенно безобидный free).

Если бага репродюсится более менее стабильно, то ЕДИНСТВЕННЫМ реальным способом ее локализовать является постепенное выкусывание функционала, причем лучше всего что то типа бинарного поиска: откусили примерно половину кода - если продолжает падать - ищем в оставшемя, если перестало - в откусанном.
Других путей много - беда в том, что обьяснять долго 16.07.08 19:25  
Автор: Neznaika <Alex> Статус: Member
Отредактировано 16.07.08 21:51  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
Давай его - в Zip и на ftp. Я вытащу.
Если callback функция (та, ссылка на которую передается в... 15.07.08 18:13  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
> > В-третьих. Сдается мне, что здесь - даже и без *.map
> файла
> > - все понятно.
> > Ваша программа вызывает системную функцию
> > EnumFontFamiliesEx. Одним из параметов
> EnumFontFamiliesEx
> > является callback-функция (функция обратного вызова;
> т.е,
> > программист сам эту функцию не вызывает, она
> вызывается
> > системой Windows). И эта callback-функция у вас
> написана с
> > ошибкой. Возможно, в ней не проверяются входные
> параметры.
> > Или она не обьявлена как экпортируемая. Или она
> обьявлена
> > как fastcall. Или она пишет в область памяти, которая
> не
> > проинициализирована. Или еще что-нибудь.
> В программе используется всякая дрянь типа DeveloperExpress
> и FastReport, боюсь что им вызов EnumFont* необходим...

Если callback функция (та, ссылка на которую передается в функцию EnumFontFamiliesEx) не очень большая, то исходник в студию.
Куча спама, вроде бы ничего крамольного... 15.07.08 19:09  
Автор: Ustin <Ustin> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
begin
  TStrings(Data).AddObject(LogFont.lfFaceName, Pointer(FontType and TRUETYPE_FONTTYPE <> 0));
  Result := 1;
end;

---
function EnumFontsProc2(AFontLoader: TcxFontLoader; const ALogFont: TLogFont;
  AFontType: DWORD): Integer;
var
  AFaceName: string;
begin
  AFaceName := ALogFont.lfFaceName;
  if (AFontLoader.FontList.IndexOf(AFaceName) = -1) and
    IsValidFontCondition(AFontLoader.FFontTypes, ALogFont, AFontType) then
  begin
    if ALogFont.lfCharSet = SYMBOL_CHARSET then
      AFontType := AFontType or SYMBOL_FONTTYPE;
    if ALogFont.lfPitchAndFamily = FIXED_PITCH then
      AFontType := AFontType or FIXEDPITCH_FONTTYPE;
    AFontLoader.FontList.AddObject(AFaceName, TObject(Integer(AFontType)));
  end;
  if AFontLoader.Terminated then
    Result := 0
  else
    Result := 1;
end;

function EnumFontsProc1(var ALogFont: TLogFont;
  var ATextMetric: TTextMetric; AFontType: DWORD;
  AData: LPARAM): Integer; stdcall;
begin
  Result := EnumFontsProc2(TcxFontLoader(AData), ALogFont, AFontType);
end;


---
function QRRTFEnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
  FontType: Integer; Data: Pointer): Integer; stdcall;
var
  S: TStrings;
  Temp: string;
  Family: integer;
begin
  S := TStrings(Data);
  Temp := LogFont.lfFaceName;
  Family := LogFont.lfPitchAndFamily shr 4;
  if (S.Count = 0) or (AnsiCompareText(S[S.Count-1], Temp) <> 0) then
    S.AddObject(Temp, TObject(Family));
  Result := 1;
end;

---
function EnumFontCharsets(var EnumLogFont: TEnumLogFontEx;
  PTextMetric: PNewTextMetricEx; FontType: Integer; Data: LPARAM): Integer;
  export; stdcall;
var s: String;
    l,cs: Integer;
begin
  Result := 1;
  cs := EnumLogFont.elfLogFont.lfCharSet;
  if cs<>MAC_CHARSET then begin
    l := StrLen(EnumLogFont.elfScript);
    SetLength(s,l);
    Move(EnumLogFont.elfScript, PChar(s)^,  l);
    for l := 0 to TRVFontCharsetComboBox(Data).Items.Count-1 do begin
      if Integer(TRVFontCharsetComboBox(Data).Items.Objects[l])=cs then
        exit;
      if AnsiCompareText(TRVFontCharsetComboBox(Data).Items[l],s)>0 then begin
        TRVFontCharsetComboBox(Data).Items.InsertObject(l,s,TObject(cs));
        exit;
      end;
    end;
    TRVFontCharsetComboBox(Data).Items.AddObject(s, TObject(cs));
  end;
end;

---
function EnumFontsProc(var ALogFont: TLogFont; var ATextMetric: TTextMetric;
  AFontType: DWORD; AData: LPARAM): Integer; stdcall;
begin
  if ALogFont.lfCharSet = SYMBOL_CHARSET then
    AFontType := AFontType or SYMBOL_FONTTYPE;
  if ALogFont.lfPitchAndFamily = FIXED_PITCH then
    AFontType := AFontType or FIXEDPITCH_FONTTYPE;
  FFontList.AddObject(ALogFont.lfFaceName, TObject(Integer(AFontType)));
  Result := 0;
end;

---
Сдается мне, что 15.07.08 20:36  
Автор: Neznaika <Alex> Статус: Member
Отредактировано 15.07.08 21:30  Количество правок: 2
<"чистая" ссылка> <обсуждение закрыто>
1) EnumFontsProc2 - не обьявлена как stdcall. Причем на входе - не 4 параметра, а только 3.
Это фатальная ошибка.
И в добавок, многопоточность - неправильно реализована. Поэтому в синий экран и падает.

2) EnumFontCharsets - обьявлена как export.
Не фатально, но "export" надо выкинуть.

3) Ни в одной из функций - не вижу проверки входных параметров.
Для функций обратного вызова - это обязательно.
Ды вроде хелпы говорят не так... 16.07.08 09:49  
Автор: Ustin <Ustin> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> 1) EnumFontsProc2 - не обьявлена как stdcall. Причем на
> входе - не 4 параметра, а только 3.
> Это фатальная ошибка.
> И в добавок, многопоточность - неправильно реализована.
> Поэтому в синий экран и падает.
EnumFontsProc2 - всего лишь вызывается из callback, такая запись - обычная практика в delphi
За многопоточность - не могу понять где ошибка...

> 2) EnumFontCharsets - обьявлена как export.
> Не фатально, но "export" надо выкинуть.
The directives near, far, and export refer to calling conventions in 16-bit Windows programming. They have no effect in Win32, or in .NET applications and are maintained for backward compatibility only

> 3) Ни в одной из функций - не вижу проверки входных
> параметров.
> Для функций обратного вызова - это обязательно.
Эмм... проверки на что? Логика вроде как именно на них и базируется :)
Насчет того, что баг - в винде, это ты пожалуй, загнул слегка 16.07.08 19:19  
Автор: Neznaika <Alex> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
Баг - у Вас в программе. Вот смотри:

1) EnumFontsProc2:
Для правильной реализации многопоточности - надо использовать блокировки.
Блокировки чаще всего делаются через EnterCriticalSection/LeaveCriticalSection

2) EnumFontCharsets:
Правильно, export - только для обратной совместимости. И поэтому его надо выкинуть.
Что будет, если одновременно ставить export и stdcall -- никто в компаниии Borland не проверял.

3) Про проверку входных параметров:
Это когда один из параметров описан как "Data: Pointer". И он всегда может быть нулевым.
А ты без проверки - делаешь S := TStrings(Data);
1  |  2 >>  »  






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2021 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach