Всем привет!
Я с asio и boost только начинаю работать и вот наткнулся на проблему.
Суть ее в том, что вываливается исключение при работе с boost::asio::placeholders.
Например, я делаю следующий вызов async_accept:
pacceptor_->async_accept(pclient->GetSocket(),
boost::bind(&CNetCopyServer::OnAccept, this, pclient,
boost::asio::placeholders::error));
Возникает исключение
Unhandled exception at 0x0053ae4e in MDBCopySrv.exe: 0xC0000005: Access violation reading location 0x00000000.
Посмотрев в дисассемблере, увидел что исключение получается на строчке:
EAX = 0 и следовательно получаем исключение. Но из-за чего такое происходит?
Что я не так сделал, ведь вроде бы по туториалу пытался сделать..?
Заранее спасибо за помощь
Здравствуйте, savitar, Вы писали:
S>Ничего криминального в указанном месте нет. Видимо где-то память хериться.
Как оказалось дело было в следующем.
В самом начале запуска программы происходит инициализация глобальных переменных,
в том числе и boost::asio::placeholders::error
После этого вывоза она инициализируется, все хорошо.. &error показывает валидный адрес
Эта инициализация вызывается три раза. Причем между ними &error показывает 0.
Моя программа — это сервис windows, и я делаю ее с помощью ATL, где
есть класс CAtlServiceModuleT, который помогает в создании сервиса и управлении им.
Создание внутренних объектов происходит прямо в конструкторе моего унаследованного класса.
CMDBCopySrvModule() : CAtlServiceModuleT()
{
m_pCopyManager = new CCopyManager();
m_pNetServer = new CNetCopyServer(m_pCopyManager);
m_pNetServer->StartServer();
}
Объект этого класса тоже является глобальной переменной и ее создание происходит вместе с placeholders::error.
Причем она вклинивается между теми тремя инициализациями placeholders::error.
И получается что уже в конструкторе моего класса &error = 0.
(На момент входа в этот конструктор &error еще валидный. Но дальше происходит нечто странное.
Как только я захожу в конструктор CCopyManager, &error становиться равен 0.)
Проблема решилась переносом создания внутренних объектов в метод RunMessageLoop.
Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы.
Но я по-прежнему не понимаю где &error успевает обнуляться между этими вызовами и почему их три?
CRT каким-то хитрым способом строит список инициализации или что?
Здравствуйте, fk, Вы писали:
fk>Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы.
в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит?
fk>CRT каким-то хитрым способом строит список инициализации или что?
у vc++ можно ведь самому установить порядок инициализации глобальных переменных, вот только не помню директиву.
Здравствуйте, о_О, Вы писали:
о_О>Здравствуйте, fk, Вы писали:
fk>>Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы. о_О>в asio какое-то порно с глобальными переменными.
Глобальные переменные — это как езда по разделительной полосе. Всё ОК, пока не ещё одного такого же не встретишь.
Здравствуйте, о_О, Вы писали:
fk>>Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы. о_О>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит?
Здравствуйте, jazzer, Вы писали:
fk>>>Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы. о_О>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит?
J>багрепорт уже отправили им?
Здравствуйте, Mazay, Вы писали:
M>Здравствуйте, jazzer, Вы писали:
fk>>>>Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы. о_О>>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит?
J>>багрепорт уже отправили им?
M>Какой смысл? Всё равно нормального решения нет.
Ну О_о, видимо, решение знает, раз так резко высказывается...
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, о_О, Вы писали:
fk>>>Получается что нельзя пользоваться asio в конструкторе глобальных объектов, так как некоторые его объекты еще не до конца созданы. о_О>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит?
J>багрепорт уже отправили им?
зачем? что я ему скажу? "эй, линуксоид, кто ж WSAStartup на глобальную переменную вешает?"
Здравствуйте, о_О, Вы писали:
о_О>>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит? J>>багрепорт уже отправили им? о_О>зачем? что я ему скажу? "эй, линуксоид, кто ж WSAStartup на глобальную переменную вешает?"
если уберешь "линуксоид" и приведешь вместо этого цитату из MSDN, а еще лучше, пример падающей программы — то да.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, о_О, Вы писали:
о_О>>>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит? J>>>багрепорт уже отправили им? о_О>>зачем? что я ему скажу? "эй, линуксоид, кто ж WSAStartup на глобальную переменную вешает?"
J>если уберешь "линуксоид" и приведешь вместо этого цитату из MSDN, а еще лучше, пример падающей программы — то да.
нуу... эту проблему можно решить путем добавления флага компиляции ASIO_MANUAL_INITIALIZATION, но...
Здравствуйте, о_О, Вы писали:
о_О>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, о_О, Вы писали:
о_О>>>>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит? J>>>>багрепорт уже отправили им? о_О>>>зачем? что я ему скажу? "эй, линуксоид, кто ж WSAStartup на глобальную переменную вешает?"
J>>если уберешь "линуксоид" и приведешь вместо этого цитату из MSDN, а еще лучше, пример падающей программы — то да.
о_О>нуу... эту проблему можно решить путем добавления флага компиляции ASIO_MANUAL_INITIALIZATION, но...
о_О>*тут было очень много разоблачающего текста*
Здравствуйте, jazzer, Вы писали:
J>Давай ты это все изложишь на английском и трекере буста, а сюда ссылку? J>Я тебе даже помогу: J>https://svn.boost.org/trac/boost/newticket
Давно "мечтал", чтобы инициализация и деинициализация Asio были вынесены явно (например, в некоторый scoped guard класс). Вообще, мне кажется, любая библиотека, требующая инициализации/деинициализация должна позволять делать это явно (если не требовать). Ваше мнение?
Вот еще кое-что по теме, но из другого "королевства" — TBB initialization, termination, and resource management details, juicy and gory:
This means that auto-initialization, with all its convenience, may restrict your ability to control concurrency of parallel computations. The only consolation is that fortunately this is rarely an issue in practice.
Programs must be written for people to read, and only incidentally for machines to execute
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, о_О, Вы писали:
о_О>>Здравствуйте, jazzer, Вы писали:
J>>>Здравствуйте, о_О, Вы писали:
о_О>>>>>>в asio какое-то порно с глобальными переменными. в курсе, что WSAStartup вызывается так же и чем это грозит? J>>>>>багрепорт уже отправили им? о_О>>>>зачем? что я ему скажу? "эй, линуксоид, кто ж WSAStartup на глобальную переменную вешает?"
J>>>если уберешь "линуксоид" и приведешь вместо этого цитату из MSDN, а еще лучше, пример падающей программы — то да.
о_О>>нуу... эту проблему можно решить путем добавления флага компиляции ASIO_MANUAL_INITIALIZATION, но...
о_О>>*тут было очень много разоблачающего текста*
J>Давай ты это все изложишь на английском и трекере буста, а сюда ссылку? J>Я тебе даже помогу: J>https://svn.boost.org/trac/boost/newticket
Здравствуйте, abrarov, Вы писали:
A>Вообще, мне кажется, любая библиотека, требующая инициализации/деинициализация должна позволять делать это явно (если не требовать). Ваше мнение?
она обязана не производить инициализацию/деинициализацию автоматически, если используются системные библиотеки. это требование Windows, а требования API ОС надо соблюдать
но конкретно крис колхоф — линуксоид и такое порно у него уже 8 лет
Ну хотя бы с WSAStartup/WSACleanup там есть решение. Да. Что касается boost::asio::placeholders, то они мне "сразу не понравились". Перейду на boost::arg<> и на _N.
Programs must be written for people to read, and only incidentally for machines to execute