创建ACE_Message_Block时size为什么发生了变化?
大家帮忙看下这个问题:#00x0020f7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#10x002547a5 in raise () from /lib/tls/libc.so.6
#20x00256209 in abort () from /lib/tls/libc.so.6
#30x0028871a in __libc_message () from /lib/tls/libc.so.6
#40x0028f99c in _int_malloc () from /lib/tls/libc.so.6
#50x00291401 in malloc () from /lib/tls/libc.so.6
#60x001b1456 in operator new () from /usr/lib/libstdc++.so.6
#70x001b1508 in operator new[] () from /usr/lib/libstdc++.so.6
#80x006db123 in ACE_New_Allocator::malloc (this=0x79a3a0, nbytes=80) at ../../ace/Malloc_Allocator.cpp:118
#90x006dcdcc in ACE_Data_Block (this=0x9f93c970, size=4294967272, msg_type=1, msg_data=0x0, allocator_strategy=0x0, locking_strategy=0x0, flags=0,
data_block_allocator=0x79a3a0) at ../../ace/Message_Block.cpp:368
#10 0x006dd738 in ACE_Message_Block::init_i (this=0x9fd86030, size=80, msg_type=1, msg_cont=0x0, msg_data=0x0, allocator_strategy=0x0,
locking_strategy=0x0, flags=0, priority=0, execution_time=@0x80fd590, deadline_time=@0x80fd5e0, db=0x9f93c970, data_block_allocator=0x79a3a0,
message_block_allocator=0x0) at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/new:92
#11 0x006de21b in ACE_Message_Block (this=0x9fd86030, size=80, msg_type=1, msg_cont=0x0, msg_data=0x0, allocator_strategy=0x0, locking_strategy=0x0,
priority=0, execution_time=@0x80fd590, deadline_time=@0x80fd5e0, data_block_allocator=0x0, message_block_allocator=0x0)
at ../../ace/Message_Block.cpp:453
为什么构造ACE_Message_Block时穿进去的size=80,走到ACE_Message_Block::init_i 时也是size=80,但是在init_i中创建ACE_Data_Block时却变成了size=4294967272.
创建就用了
ACE_Message_Block *mb = 0;
ACE_NEW (mb, ACE_Message_Block (80));
[ 本帖最后由 denis_lan 于 2009-12-1 15:51 编辑 ] 这么简单的用法应该不会出错吧。
后来new出来的ACE_Message_Block 正常么?
那个size是不是 ACE_Data_Block 还没完成初始化的时候的值(-1)?
可以仔细看看ACE_Message_Block::init_i的代码 谢谢版主这么快回答。
是的,就是这么简单的用法。根据core_dump看,就是由于size发生了变化(变成了很大的数),导致new失败(abort)
ACE_Message_Block (size=80) :
11 0x006de21b in ACE_Message_Block (this=0x9fd86030, size=80, msg_type=1, msg_cont=0x0, msg_data=0x0, allocator_strategy=0x0, locking_strategy=0x0,
priority=0, execution_time=@0x80fd590, deadline_time=@0x80fd5e0, data_block_allocator=0x0, message_block_allocator=0x0)
at ../../ace/Message_Block.cpp:453
ACE_Message_Block::init_i (size=80)
#10 0x006dd738 in ACE_Message_Block::init_i (this=0x9fd86030, size=80, msg_type=1, msg_cont=0x0, msg_data=0x0, allocator_strategy=0x0,
locking_strategy=0x0, flags=0, priority=0, execution_time=@0x80fd590, deadline_time=@0x80fd5e0, db=0x9f93c970, data_block_allocator=0x79a3a0,
message_block_allocator=0x0) at /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/new:92
在init_i 里创建ACE_Data_Block时就变了
int
ACE_Message_Block::init_i (size_t size,
ACE_Message_Type msg_type,
ACE_Message_Block *msg_cont,
const char *msg_data,
ACE_Allocator *allocator_strategy,
ACE_Lock *locking_strategy,
Message_Flags flags,
unsigned long priority,
const ACE_Time_Value &execution_time,
const ACE_Time_Value &deadline_time,
ACE_Data_Block *db,
ACE_Allocator *data_block_allocator,
ACE_Allocator *message_block_allocator)
{
ACE_TRACE ("ACE_Message_Block::init_i");
ACE_FUNCTION_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_ENTER);
this->rd_ptr_ = 0;
this->wr_ptr_ = 0;
this->priority_ = priority;
#if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
this->execution_time_ = execution_time;
this->deadline_time_ = deadline_time;
#else
ACE_UNUSED_ARG (execution_time);
ACE_UNUSED_ARG (deadline_time);
#endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
this->cont_ = msg_cont;
this->next_ = 0;
this->prev_ = 0;
this->message_block_allocator_ = message_block_allocator;
if (this->data_block_ != 0)
{
this->data_block_->release ();
this->data_block_ = 0;
}
if (db == 0)
{
if (data_block_allocator == 0)
ACE_ALLOCATOR_RETURN (data_block_allocator,
ACE_Allocator::instance (),
-1);
ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC);
// Allocate the <ACE_Data_Block> portion, which is reference
// counted.
ACE_NEW_MALLOC_RETURN (db, // 这里生成ACE_Data_Block
static_cast<ACE_Data_Block *> (
data_block_allocator->malloc (sizeof (ACE_Data_Block))),
ACE_Data_Block (size,
msg_type,
msg_data,
allocator_strategy,
locking_strategy,
flags,
data_block_allocator),
-1);
ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR);
// Message block initialization may fail, while the construction
// succeds.Since ACE may throw no exceptions, we have to do a
// separate check and clean up, like this:
if (db != 0 && db->size () < size)
{
db->ACE_Data_Block::~ACE_Data_Block();// placement destructor ...
data_block_allocator->free (db); // free ...
errno = ENOMEM;
return -1;
}
}
// Reset the data_block_ pointer.
this->data_block (db);
return 0;
}
ACE_Data_Block::ACE_Data_Block (size_t size,
ACE_Message_Block::ACE_Message_Type msg_type,
const char *msg_data,
ACE_Allocator *allocator_strategy,
ACE_Lock *locking_strategy,
ACE_Message_Block::Message_Flags flags,
ACE_Allocator *data_block_allocator)
: type_ (msg_type),
cur_size_ (0), // Reset later if memory alloc'd ok
max_size_ (0),
flags_ (flags),
base_ (const_cast <char *> (msg_data)),
allocator_strategy_ (allocator_strategy),
locking_strategy_ (locking_strategy),
reference_count_ (1),
data_block_allocator_ (data_block_allocator)
{
ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR2_ENTER);
// If the user didn't pass one in, let's use the
// <ACE_Allocator::instance>.
if (this->allocator_strategy_ == 0)
ACE_ALLOCATOR (this->allocator_strategy_,
ACE_Allocator::instance ());
if (this->data_block_allocator_ == 0)
ACE_ALLOCATOR (this->data_block_allocator_,
ACE_Allocator::instance ());
if (msg_data == 0)
{
ACE_ALLOCATOR (this->base_,
(char *) this->allocator_strategy_->malloc (size)); // 根据core_dump看,这里size就不对了
#if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
(void) ACE_OS::memset (this->base_,
'\0',
size);
#endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
}
// ACE_ALLOCATOR returns on alloc failure but we cant throw, so setting
// the size to 0 (i.e. "bad bit") ...
if (this->base_ == 0)
{
size = 0;
}
// The memory is legit, whether passed in or allocated, so set
// the size.
this->cur_size_ = this->max_size_ = size;
}
errno = ENOMEM;
return -1;
}
}
// Reset the data_block_ pointer.
this->data_block (db);
return 0;
}
#90x006dcdcc in ACE_Data_Block (this=0x9f93c970, size=4294967272, msg_type=1, msg_data=0x0, allocator_strategy=0x0, locking_strategy=0x0, flags=0,
data_block_allocator=0x79a3a0) at ../../ace/Message_Block.cpp:368
很奇怪。
另外,程序运行所在的服务器是每10分钟和一台时间服务器进行同步的,不知道这个有没有影响。
ACE_Message_Block是在一个函数内创建的,不是类成员,是一个独立的公共函数,有多个线程会调用,没有全局变量,静态变量。会可能导致这个问题吗?
而且不是可重现的,假如其他地方有溢出,有可能导致出现这个问题吗?
[ 本帖最后由 denis_lan 于 2009-12-1 16:41 编辑 ] 多线程这样
ACE_Message_Block *mb = 0;
ACE_NEW (mb, ACE_Message_Block (80));
应该没问题,mb是auto变量。但如果mb是共享的一个指针,比如是成员变量。肯定有问题。
如果问题不可重现,很可能是多线程问题。
可以加点print语句,看一下出问题时size在哪里开始变的。例如 // size = ?
ACE_NEW_MALLOC_RETURN (db,
static_cast<ACE_Data_Block *> (
data_block_allocator->malloc (sizeof (ACE_Data_Block))),
ACE_Data_Block (size,
msg_type,
msg_data,
allocator_strategy,
locking_strategy,
flags,
data_block_allocator),
-1);// size = ?
if (msg_data == 0)
{
ACE_ALLOCATOR (this->base_,
(char *) this->allocator_strategy_->malloc (size));
[ 本帖最后由 wishel 于 2009-12-1 21:54 编辑 ] 这个size比较有意思,-1是4294967296吧,差了24
回复 #5 wishel 的帖子
mb是auto变量,不是共享的。我怀疑某处可能有溢出造成,就是不好找。
各单元测试没有问题,valgrind检查也没发现问题。(跑了很多遍,逻辑分支也很多)
怕是某种情况下累积导致触发问题,但是没规律,不重现,很是头疼。
这玩意终归是个隐患。
版主有什么好办法吗? 难重现的问题最头疼。
我一般是加print语句,不出问题时候就是多打点东西而已,但一旦出问题时打印的信息就有价值了。
可以在程序中各处加一些print语句,先找出出问题时size最早的变化位置。
回复 #7 wishel 的帖子
通过core可以看到size发生变化的位置,因为实在ACE的代码中。所以通过打印size的变化过程没有什么实际意义。我的意思是说ACE_NEW这个Message_Block时就进入ACE的代码了,实际发生变化的位置我上面也指出来了,所以我在其他环节打印是没有意义的(况且size就是在ACE_NEW中指定的,我在#1楼的帖子里有)[ 本帖最后由 denis_lan 于 2009-12-3 03:21 编辑 ] 原帖由 denis_lan 于 2009-12-2 22:57 发表 http://www.acejoy.com/bbs/images/common/back.gif
通过core可以看到size发生变化的位置,因为实在ACE的代码中。所以通过打印size的变化过程没有什么实际意义。我的意思是说ACE_NEW这个Message_Block时就进入ACE的代码了,实际发生变化的位置我上面也指出来了,所以我在其他 ...
core可以看到变化了的位置,但这个位置不一定是最早发生变化的位置。
malloc(size)的时候core dump了,但这个size在之前被多次传递。也就是说是问题体现点而不一定是问题发生点。 我的意思是,形参和实参是不同的,实参是以传值的方式压栈的,它和实参分别有不同的存储地址。
#90x006dcdcc in ACE_Data_Block (this=0x9f93c970, size=4294967272, msg_type=1, msg_data=0x0, allocator_strategy=0x0, locking_strategy=0x0, flags=0,data_block_allocator=0x79a3a0) at ../../ace/Message_Block.cpp:368
这句可以看出是ACE_Data_Block()中的实参size出了问题,但不能具体确定是否传来的形参size(它又是init_i中的实参size,init_i中的形参size是没有问题的)是否已经先出问题了。
所谓出问题也就是它所在的内存被修改了,由于都是栈上变量,不会是多线程问题,有可能是缓冲区溢出造成的。缓冲区溢出问题也有难以重现的特征。
页:
[1]
2