平台崩溃之operator new异常(二十一)-2010-8-9

平台在8-8日04:13分崩溃,平台进程还在,telnet上去立即断开。产生了crash。
分析结果日下:
STACK_TEXT: 
247cf77c 10211863 0000000c 00000001 004bf7dc MSVCRTD!_heap_alloc_dbg+0x60
247cf798 1020a53a 0000000c 00000001 00000001 MSVCRTD!_nh_malloc_dbg+0x23
247cf7b4 00486470 0000000c 00000001 004bf7dc MSVCRTD!operator new+0x1a
247cf818 0047e2c9 0000000c 247cf938 247cf89c hotfoxd!operator new+0x30 [c:/program files/microsoft visual studio/vc98/include/crtdbg.h @ 552]
247cf88c 0047e186 024e8041 024e9f5c 08dd8090 hotfoxd!_bstr_t::_bstr_t+0x39 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/common/comutil.h @ 287]
247cf948 004161af 247cfa6c 247cfa18 08dd1f80 hotfoxd!CDbAccessor2::Connect+0xf6 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/source/source/ado.cpp @ 896]
247cfa04 070a1b82 025392b1 ffffffff 024d0a01 hotfoxd!HTX_DBPool::GetDbConnection+0x27f [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/hotfox/dbpool.cpp @ 113]
247cfa6c 070a1c79 025392b1 ffffffff cccccc01 rto!CBasePlugInModule::GetDbConnection+0x52 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/source/source/baseplugin.cpp @ 210]
247cfacc 07086e55 025392b1 ffffffff 00000001 rto!GetDbConnection+0x29 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/source/source/baseplugin.cpp @ 225]
247cfb30 070979de 025392b1 00000002 247cfe20 rto!CDBCGETTER2::GetDBC+0x35 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/source/include/baseplugin.h @ 295]
247cfd98 07083099 247cfdf8 247cfe8c 247cfe34 rto!CSEMQ::GetData+0x6e [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/common/semq.cpp @ 692]
247cfe2c 07096dec 247cfef4 247cfe98 08dd1f80 rto!CSepSEMQ::GetData+0x119 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/sevs/rto/psemq.cpp @ 106]
247cfe8c 0041a459 02538560 00000000 00000000 rto!GetDataProc+0x4c [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/common/semq.cpp @ 583]
247cfef4 01625ab7 08dd0c70 00000000 00000000 hotfoxd!exec_task_func+0x49 [e:/svn/workdb/1?ó|±|/branches/rb-2.5.11/server/hotfox/deamontask.cpp @ 29]
WARNING: Stack unwind information not available. Following frames may be wrong.
247cff44 016259e4 08dd1980 08dd7320 87acd5f8 aced+0xa5ab7
247cff74 0159a836 08dd7320 247cffb8 247cffb8 aced+0xa59e4
247cff84 1020c323 08dd7320 00000000 00000000 aced+0x1a836
247cffb8 7c824829 08dd1f80 00000000 00000000 MSVCRTD!_beginthreadex+0x133
247cffec 00000000 1020c2b0 08dd1f80 00000000 kernel32!BaseThreadStart+0x34

处理过程:
(1)增加ado的异常捕获,以前是只捕获的了_com_error异常,
 catch(_com_error &e) {
  ErrorHandle(e,false);
  return false;
 }
 return true;
 现增加多任意异常的捕获,确保程序能够得到恢复,并在出现任意异常后输出日志。

 (2)修改DeamonTask类,在初始化com环境时,判断返回值,当失败时,记录日志,并退出后台任务
  ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
 status = (*task->func_)(task->arg_);
 //::CoUninitialize();

 (4)修改sdk中的HTX_Task_Base任务基类
 a)增加初始化com环境失败的日志
 b)增加任务退出日志,并释放com环境
 int HTX_Task_Base::svc()
{
 ACE_Message_Block *mb = 0;

 ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
 for( mb=0; ; )  {
//  if( this->getq(mb) == -1 )
  if (this->msg_queue()->dequeue_head(mb)==-1)
   ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p/n"),ACE_TEXT ("getq")),-1);

  ///< 结束任务
  if (mb->msg_type () == ACE_Message_Block::MB_HANGUP) {
   if (this->putq (mb->duplicate ()) == -1) { ///< @question 为什么不加此行,task无法结束(停止在wait上)
    ACE_ERROR_RETURN ((LM_ERROR,ACE_TEXT ("%p/n"),ACE_TEXT ("Task::svc() putq")),-1);
   }
   mb->release ();
   break;
  }

  ///< 处理消息块
  try {
  handle_message_block(mb);
  } catch(...) { ///< @todo 1.写入日志文件 2.记录是哪个任务产生的
  }

  ///< 释放消息块
  mb->release();
 }
 
 ::CoUninitialize();
 return 0;
}

(3)hotfox_thr_proc线程(前摄器主循环)增加初始化COM环境
ACE_THR_FUNC_RETURN hotfox_thr_proc (void *arg) {
 ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
 SYSTEM_INFO si;
 GetSystemInfo(&si);
 ACE_Proactor::instance()->number_of_threads(si.dwNumberOfProcessors);
 ACE_Proactor::instance ()->proactor_run_event_loop ();
 ::CoUninitialize();
 return 0;
}

(4)网上资料:http://www.pcreview.co.uk/forums/thread-2496163.php
 _bstr_t leads to a crash

--------------------------------------------------------------------------------


Hi All,

Sorry, for the delay in reply. The _bstr_t variable used in my code
contains a SQL command and is then passed to ADO function. An Execute()
fuction of _ConnectionPtr in ADO is used to execute the SQL command.

In my further investigation I found that while running the program in
debug mode the application gives an error "The Value of ESP not saved
properly accross function calls...". This error occurs in Execute()
function of _ConnectionPtr. If I ignore this message, then my _bstr_t
variable contain a garbled message and the application crash.
Any help as regard to why this error message comes or how this could be
solved would be very helpful to me.

Thanks for your replies and hope I would be able to solve my problem
with your help.

Regards,
Ashish Choudhary

Bronek Kozicki wrote:
> *Willy Denoyette [MVP] wrote:
> > No, this is not true. The _bstr_t wrapper does not depend on the
> COM library
> > (initialized by a CoInitialize call), you can use this class
> without calling
>
> indeed, you are right, thanks for rectifying my mistake. However, if
> there is
> any use of other COM wrappers (#import etc), these will release COM
> objects at
> the point of their destruction (end of scope). If that comes after
> CoUninitialize, memory access violation will happen. The other thing
> coming to
> my mind is misuse of _bstr_t , I gave explanation and code samples in
> this thread:
> http://groups.google.com/group/micr...1a3e407b6b25f0/
>
>
> B. *

(3)http://bytes.com/topic/net/answers/477361-_bstr_t-leads-crash
_bstr_t leads to a crash
ashish_chap    Posts: n/a
#1: Apr 6 '06 
 

Hi,

I am using _bstr_t class in a function. This is used in an application
that is used in an multi-threaded environment. The function is
implemented as follows:

int Function(wchar_t *sqlCmd)
{
_bstr_t cmd ;

cmd = sqlCmd ;
CoInitialize(NULL);
..
..
..
return 0;
}


The above function uses ADO functions to execute SQL command. Here, in
statement

cmd = sqlCmd

while executing sqlCmd "Sometimes" an exception is thrown this happens
because though sqlCmd contains the sqlCmd to be executed. It is not
assigned to cmd which is passed to Execute function of ADODB.

Also, it crashes sometimes when the function returns and destructor for
_bstr_t is called.

Please, help me find out the answers to the following questions.
1) Is there any limitation for the overloaded '=' operation in _bstr_t,
due to which somestimes the sqlCmd is not assigned to cmd.

2)Before calling the destructor for _bstr_t is there any operation that
should be used to avoid the crash?

Thanks for you time.

Regards,
Ashish Choudhary

 

--
ashish_chap
------------------------------------------------------------------------
Posted via http://www.codecomments.com
------------------------------------------------------------------------

 

 

Bronek Kozicki    Posts: n/a
#2: Apr 6 '06 
 
re: _bstr_t leads to a crash

--------------------------------------------------------------------------------

ashish_chap wrote:[color=blue]
> I am using _bstr_t class in a function. This is used in an application
> that is used in an multi-threaded environment. The function is
> implemented as follows:
> Also, it crashes sometimes when the function returns and destructor for
> _bstr_t is called.
>
> Please, help me find out the answers to the following questions.
> 1) Is there any limitation for the overloaded '=' operation in _bstr_t,
> due to which somestimes the sqlCmd is not assigned to cmd.
>
> 2)Before calling the destructor for _bstr_t is there any operation that
> should be used to avoid the crash?[/color]


as _bstr_t is simply encapsulation for COM support functions (SysAllocString,
SysFreeString etc. ) You should not use these function when COM susbsystem is
(not yet or already) unavailable. What you do is:

1. initialize _bstr_t before COM is available (_bstr_t may delay call to
SysAllocString till you actually put something in it, but you are still in danger)

2. I also guess that you call CoUninitialize before _bstr_t destructor is
called. This means that when SysFreeString is called, there is no COM
sybsystem to handle your call.

What you should do is to initialize COM before you start any COM-related
activity and un-initialize when you are 100% done. Like here:

#include <cstdio>
#include <stdexcept>

#include <comdef.h>
#include <comutil.h>

int main()
{
int result = 13;
if (FAILED(CoInitialize(NULL)))
{
puts("Failed to initialize COM");
return result;
}

try
{
_bstr_t a = "blablabla";
// .... call your functions that use COM
result = 0;
}
catch(std::exception& e)
{
puts(e.what());
result = 1;
}
catch(_com_error e)
{
puts(static_cast<const char*>(e.Description()));
result = 2;
}

CoUninitialize();
return result;
}


B.
 

Willy Denoyette [MVP]    Posts: n/a
#3: Apr 6 '06 
 
re: _bstr_t leads to a crash

--------------------------------------------------------------------------------

No, this is not true. The _bstr_t wrapper does not depend on the COM library
(initialized by a CoInitialize call), you can use this class without calling
into COM.

Willy.

"Bronek Kozicki" <[email protected]> wrote in message
news:[email protected]...
| ashish_chap wrote:
| > I am using _bstr_t class in a function. This is used in an application
| > that is used in an multi-threaded environment. The function is
| > implemented as follows:
| > Also, it crashes sometimes when the function returns and destructor for
| > _bstr_t is called.
| >
| > Please, help me find out the answers to the following questions.
| > 1) Is there any limitation for the overloaded '=' operation in _bstr_t,
| > due to which somestimes the sqlCmd is not assigned to cmd.
| >
| > 2)Before calling the destructor for _bstr_t is there any operation that
| > should be used to avoid the crash?
|
|
| as _bstr_t is simply encapsulation for COM support functions
(SysAllocString,
| SysFreeString etc. ) You should not use these function when COM susbsystem
is
| (not yet or already) unavailable. What you do is:
|
| 1. initialize _bstr_t before COM is available (_bstr_t may delay call to
| SysAllocString till you actually put something in it, but you are still in
danger)
|
| 2. I also guess that you call CoUninitialize before _bstr_t destructor is
| called. This means that when SysFreeString is called, there is no COM
| sybsystem to handle your call.
|
| What you should do is to initialize COM before you start any COM-related
| activity and un-initialize when you are 100% done. Like here:
|
| #include <cstdio>
| #include <stdexcept>
|
| #include <comdef.h>
| #include <comutil.h>
|
| int main()
| {
| int result = 13;
| if (FAILED(CoInitialize(NULL)))
| {
| puts("Failed to initialize COM");
| return result;
| }
|
| try
| {
| _bstr_t a = "blablabla";
| // .... call your functions that use COM
| result = 0;
| }
| catch(std::exception& e)
| {
| puts(e.what());
| result = 1;
| }
| catch(_com_error e)
| {
| puts(static_cast<const char*>(e.Description()));
| result = 2;
| }
|
| CoUninitialize();
| return result;
| }
|
|
| B.


 

Willy Denoyette [MVP]    Posts: n/a
#4: Apr 6 '06 
 
re: _bstr_t leads to a crash

--------------------------------------------------------------------------------

Is this function a thread procedure? Then you need to CoUnitialize before
returning.
If it's not a thread proc, you should not CoInitialize here.

Willy.

"ashish_chap" <[email protected]> wrote in message
news:[email protected]...
|
| Hi,
|
| I am using _bstr_t class in a function. This is used in an application
| that is used in an multi-threaded environment. The function is
| implemented as follows:
|
| int Function(wchar_t *sqlCmd)
| {
| _bstr_t cmd ;
|
| cmd = sqlCmd ;
| CoInitialize(NULL);
| .
| .
| .
| return 0;
| }
|
|
| The above function uses ADO functions to execute SQL command. Here, in
| statement
|
| cmd = sqlCmd
|
| while executing sqlCmd "Sometimes" an exception is thrown this happens
| because though sqlCmd contains the sqlCmd to be executed. It is not
| assigned to cmd which is passed to Execute function of ADODB.
|
| Also, it crashes sometimes when the function returns and destructor for
| _bstr_t is called.
|
| Please, help me find out the answers to the following questions.
| 1) Is there any limitation for the overloaded '=' operation in _bstr_t,
| due to which somestimes the sqlCmd is not assigned to cmd.
|
| 2)Before calling the destructor for _bstr_t is there any operation that
| should be used to avoid the crash?
|
| Thanks for you time.
|
| Regards,
| Ashish Choudhary
|
|
|
| --
| ashish_chap
| ------------------------------------------------------------------------
| Posted via http://www.codecomments.com
| ------------------------------------------------------------------------
|


 

Bronek Kozicki    Posts: n/a
#5: Apr 7 '06 
 
re: _bstr_t leads to a crash

--------------------------------------------------------------------------------

Willy Denoyette [MVP] wrote:[color=blue]
> No, this is not true. The _bstr_t wrapper does not depend on the COM library
> (initialized by a CoInitialize call), you can use this class without calling[/color]

indeed, you are right, thanks for rectifying my mistake. However, if there is
any use of other COM wrappers (#import etc), these will release COM objects at
the point of their destruction (end of scope). If that comes after
CoUninitialize, memory access violation will happen. The other thing coming to
my mind is misuse of _bstr_t , I gave explanation and code samples in this thread:
http://groups.google.com/group/micro...a3e407b6b25f0/

于20:00替换程序,重启平台

你可能感兴趣的:(exception,function,application,平台,2010,destructor)