HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Это я глючу, или мой компьютер?
А у вас было такое чувство, будто не знаешь, проснулся ты, или спишь?
  Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



Это я глючу, или мой компьютер?

Заранее прошу отнестись к этому вопросу сурьёзно, ибо непонятное поведение движка, наблюдаемое мной, никак не является следствием похмелья или других эффектов от злоупотребления различными нехорошими излишествами

Вопрос этот вызван следующей проблемой: есть класс, и в нём объявлен метод, который ничего не делает, кроме как загружает звук функцией PRECACHE_SOUND. Но когда этот метод выполняется (вызываю я его, естественно, из функции Spawn, т.к. загрузка разрешена только в момент спавна ентитей), то игра вылетает, а в консоль выводится сообщение, что невозможно загрузить МОДЕЛЬ. И в качестве имени модели выдаётся имя того самого звука, который я пытаюсь загрузить.

Ошибок типа "вместо PRECACHE_SOUND я вызвал PRECACHE_MODEL" или "попутал аргумент функции", в коде нету. Я проверил при помощи всяких алертов и т.п, и нет никаких сомнений, что вызывается именно функция PRECACHE_SOUND, и именно она является причиной вот такого сообщения.

И как вообще такое может быть? g_engfuncs я не трогал. Могла ли она как-то неявно перетащиться в другую область памяти так, что адрес pfnPrecacheSound заменился на адрес pfnPrecacheModel?

Сообщить модератору | IP: Записан
Сообщение: 39338

Старое сообщение 14-11-2008 18:49
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 35072
Нанёс повреждений: 515 ед.
Возраст: 39

Рейтинг



Награды
 
[1 награда]


Цитата:
LLAPb писал:
Могла ли она как-то неявно перетащиться в другую область памяти так, что адрес pfnPrecacheSound заменился на адрес pfnPrecacheModel?

Да, могла. В с++ вообще контроля за памятью нет, и из-за неудачного указателя может произойти что угодно.
Но лучше приведи побольше инфы: кусок кода, точный текст, который выводится в консоль, и т.п.

__________________

Сообщить модератору | IP: Записан
Сообщение: 39340

Старое сообщение 14-11-2008 18:58
-
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



XaeroX Я думаю, кусок кода ничего не скажет, ибо он лишь вызывает PRECACHE_SOUND и всё. А вот насчёт неудачного указателя попрошу поподробней

В коде я в последнее время стал использовать операторы new/delete, мож, это из-за этого? (Но, опять же, они вызываются во многих местах, сюда этот код не влезет) Я чё-то и не предполагал, что в с++ нет контроля за памятью. Динамические массивы могут перемещаться куда хотят - это да, но чтоб и всё остальное...

Добавлено 14-11-2008 в 22:17:

Вообще, с подробной инфой тут проблематично, халфа и сорцы у меня на другом компе...

Сообщить модератору | IP: Записан
Сообщение: 39341

Старое сообщение 14-11-2008 19:17
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 35072
Нанёс повреждений: 515 ед.
Возраст: 39

Рейтинг



Награды
 
[1 награда]


Цитата:
LLAPb писал:
А вот насчёт неудачного указателя попрошу поподробней

ну что тут подробнее?
В с++ вполне законна вот такая конструкция:
C++ Source Code:
char *p = new char[32];
*(p + 1000) = 100;

Сам понимаешь, что по смещению 1000 может находиться что угодно.
Попробуй сделать вот что. Замени в g_engfuncs указатель на pfnPrecacheSound на твой собственный:
C++ Source Code:
1
typedef (blablabla) PFNPRECACHESOUNDPROC;
2
PFNPRECACHESOUNDPROC engineProc;
3
 
4
int Wrap_PrecacheSound(char *s)
5
{
6
  MessageBox(0,"Precache sound", s, 0);
7
  return engineProc(s);
8
}
9
 
10
...
11
 
12
engineProc = g_engfuncs.pfnPrecacheSound;
13
g_engfuncs.pfnPrecacheSound = Wrap_PrecacheSound;

Так ты легко определишь, меняется ли структура g_engfuncs.
Еще способ - сосчитать контрольную сумму (хотя бы CRC) этой структуры при передаче в длл и периодически ее проверять.

__________________

Сообщить модератору | IP: Записан
Сообщение: 39342

Старое сообщение 14-11-2008 19:22
-
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



Ну, что такое CRC я не знаю, но я тупо посчитал количество единичек в адресах. примерно вот так:

C++ Source Code:
1
int size = sizeof(g_engfuncs.BLABLABLA)*8;
2
 
3
for (int i = 0; i < size; ++i)
4
{
5
  checksumm += ((int)g_engfuncs.BLABLABLA)&(1<<i);
6
}


Считал сначала каждый кадр, потом просто до и после вызова самых подозрительных функций - никакого эффекта. Суммы не меняются.

Первый способ, я думаю, не особо надёжен, не стал проверять.

Я конечно понимаю, что в коде у меня куча всего наворочено, и разберусь в этом только я, поэтому просто задам вопрос:

Чем (не конкретно, а например) мог быть вызван такой странный эффект? Я не имею в виду такие ляпы, как выход за границы массива, я имею в виду слегка другое. Ведь, как показала проверка контрольных сумм, указатели на функции не изменились, очевидно, куда-то сместились сами функции

Может это всё-таки связано с new/delete? Не даром же в hl.dll они вообще не юзаются...

Сообщить модератору | IP: Записан
Сообщение: 39351

Старое сообщение 14-11-2008 21:03
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 35072
Нанёс повреждений: 515 ед.
Возраст: 39

Рейтинг



Награды
 
[1 награда]


Цитата:
LLAPb писал:
Может это всё-таки связано с new/delete? Не даром же в hl.dll они вообще не юзаются...

Это маловероятно.
Вообще причина может быть на поверхности.
Сообщение какого вида? Не найдена модель блаблабла.wav или не найдена модель блаблабла.mdl?

__________________

Сообщить модератору | IP: Записан
Сообщение: 39353

Старое сообщение 14-11-2008 21:18
-
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



Не найдена модель блаблабла.wav. То есть именно тот путь, который я указываю в аргументе функции PRECACHE_SOUND.

Кхм, вообще-то контрольная сумма - вещь тоже не надёжная. Может, функции PRECACHE_SOUND & PRECACHE_MODEL поменялись местами, и сумма их адресов тогда останется неизменной. Я это говорю потому, что закомментировав вызов PRECACHE_SOUND, я наткнулся на ошибку "Не найден ЗВУК sound/models/dom_point.mdl", которая, очевидно, была вызвана функцией PRECACHE_MODEL("models/dom_point.mdl")

Так что я, пожалуй, проверю изменения каждого конкретного адреса в структуре g_engfuncs. Действительно, причина где-то на поверхности, и она, скорее всего, совершенно дурацкая...

Сообщить модератору | IP: Записан
Сообщение: 39367

Старое сообщение 15-11-2008 11:08
- За что?
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



А проблемка-то оказалась далеко не на поверхности.

Как мне удалось выяснить всякими там мессагами, алертами и т.п., в движке загрузка моделей/звуков производится то ли отдельным потоком, то ли ещё как-то так, короче, действительно модель начинает загружаться спустя определённое время после вызова PRECACHE_MODEL (даже g_ulFrameCount успевает доползти до 28-36). И при этом функции PRECACHE_blablabla не копируют свой аргумент в отдельный буфер, а используют всё тот же char* , который мы им передали. Так что если по тому адресу, куда указывает этот самый char* , будет другая строка, то мы получим вот такую ошибку.

В моём случае был указатель на буфер, общий для нескольких функций, которые писали туда имена всяких звуков, моделей и т.п.
Поэтому я стал использовать (char*)STRING(ALLOC_STRING(буфер)).

Отсюда следующий вопрос: А как движок обращается с буфером строк, в который пишется аргумент ALLOC_STRING? Если в него добавляются две одинаковые строки, то там и будут две одинаковые строки, или же одна заместит другую? (Потому что мне придётся юзать ALLOC_STRING довольно часто, но аргументы часто могут повторяться. Не вызовет ли это в конце концов переполнение памяти?)

Сообщить модератору | IP: Записан
Сообщение: 39439

Старое сообщение 19-11-2008 19:16
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 35072
Нанёс повреждений: 515 ед.
Возраст: 39

Рейтинг



Награды
 
[1 награда]


Цитата:
LLAPb писал:
А как движок обращается с буфером строк, в который пишется аргумент ALLOC_STRING? Если в него добавляются две одинаковые строки, то там и будут две одинаковые строки, или же одна заместит другую?

Если честно, не знаю Вообще-то поиск строк по большому пулу не такой уж быстрый (хотя они могут юзать хэш-таблицу, и тогда...), поэтому они вполне могли забить на проверки.
Я в движке Volatile так и делал - gi.AllocString у меня вызывал в конечном итоге malloc, и дллки должны сами были своевременно вызывать gi.FreeString (иначе были бы утечки памяти).

__________________

Сообщить модератору | IP: Записан
Сообщение: 39442

Старое сообщение 19-11-2008 20:01
-
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



XaeroX, да, действительно, в Half-Life наверное так же. Слишком уж редко это ALLOC_STRING вызывается, и нет смысла из-за столь малого количества памяти каждый раз перебирать весь пул или мутить хэш-таблицу...
Хотя, если глянуть с другой стороны, то зачем им было мутить загрузку ресурсов отдельным потоком в игре, в которой при смене карты выскакивает табличка "LOADING" и игровой процесс останавливается?
Мож они для того же понта и хэш-таблицу заюзали...

Сообщить модератору | IP: Записан
Сообщение: 39460

Старое сообщение 20-11-2008 04:11
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 35072
Нанёс повреждений: 515 ед.
Возраст: 39

Рейтинг



Награды
 
[1 награда]


Дело не в потоке вовсе... Ресурсы грузятся очень хитро. Сначала создается список этих ресурсов. Потом он пересылается с сервера на клиент (даже в случае сингла, на локалхост). Потом клиент получает мессагу, читает ее и грузит все ресурсы. А отправка мессаги идет, видимо, асинхронно, отсюда и ощущение другого потока.

__________________

Сообщить модератору | IP: Записан
Сообщение: 39462

Старое сообщение 20-11-2008 08:20
-
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



XaeroX, понятно, спасибо, учтём-с

Сообщить модератору | IP: Записан
Сообщение: 39492

Старое сообщение 20-11-2008 17:52
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 33074
Нанёс повреждений: 392 ед.

Рейтинг



У моделей, звуков и декалей общий буффер примерно на 2000 строк.
Разделение на зоны - только по старт-стоповым номерам.
Т.н. с 16 по 768 - модели, а с 768 по 1200 - звуки (это для примера).
Модельиндекс на сервере - это и есть возвращенный номер строки - пути к вашей моделке.
При старте вся эта волшебная шняжка шлется на клиент, но поскольку строк много, то делает это не за один кадр, а кадров за пять- шесть.
Но пять кадров на сервере, это кадров 30 на клиенте, отсюда и интересные значения g_ulFrameCount (PlayerThink вызывается с клиентским fps, в отличие от сервера).
Стринги, аллокнутые движком не высвобождаются автоматически и неоптимизируются в памяти никак, поскольку неизвестно будем ли мы только читать этот стринг или еще записывать.
Скажу только, что проблема с темп стрингами тянется еще с первокваки, но там её очень проблематично заметить, по причине бедности набора буилтинов. Я обычно выходил из положения создавая static стринги.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | IP: Записан
Сообщение: 39923

Старое сообщение 02-12-2008 09:29
-
LLAPb
Всея руси

Дата регистрации: Apr 2008
Проживает: Москва
Сообщений: 34
Возраст: 37

Рейтинг



Да, Дядя Миша, благодарствую, всё расписал фундоментально и по понятиям
Проблемку со строками этими я решил, создав дурацкий строковый буфер, работающий примерно как STL'овский map. В принципе, для моих целей сойдёт...

Сообщить модератору | IP: Записан
Сообщение: 39934

Старое сообщение 02-12-2008 10:48
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 19:17. Новая тема    Ответить
  Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Это я глючу, или мой компьютер?
А у вас было такое чувство, будто не знаешь, проснулся ты, или спишь?
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Crystice Softworks © 2005 - 2024