Reputation: 503
I'm trying to create a block of memory on heap and copy some data to it using memcpy, but memcpy gives a segmentation fault. I feel I have allocated enough memory, but there seems to be an invalid write. I'm not able to reason why it happens. The code where creation and memcpy happens is below I'm allocating the buffer size as (response_length+sizeof(USHORT)) because I'm copying the length in the first two bytes of the response.
typedef std::vector<UCHAR> RESPONSE_BUFFER;
typedef TimedHashMap<int, RESPONSE_BUFFER*> TimeResponseHashMap;
TimeResponseHashMap* inner_pending_response_map;
std::map<int, TimeResponseHashMap* > outer_pending_response_map;
bool
C_NORTH_WORKER_THREAD::bSaveFragmentResponse
(
int s16SessionID, int s16MessageID, UCHAR * pResponse,
USHORT response_length, VXN_PTR* const vxnptr)
{
try
{
RESPONSE_BUFFER* pResp_buffer = new RESPONSE_BUFFER(response_length+sizeof(USHORT)); //1156
memset(&pResp_buffer[0],0,(response_length+sizeof(USHORT))); //1157
memcpy(&pResp_buffer[0],&response_length,sizeof(USHORT)); //1158
memcpy((&pResp_buffer[0])+sizeof(USHORT),pResponse,response_length); //1159
}
//some more code for further processiong.
inner_pending_response_map->Insert((int)s16MessageID, pResp_buffer, expirytime); //Line 1167
if ( retval != E_SUCCESS )
{
printf("Insert failed\n");
return HD_COMMUNICATION_ERROR;
}
outer_pending_response_map.insert(make_pair((int)s16SessionID, inner_pending_response_map));
}
Definition of Insert Function:
template <typename Key, typename ElementObject>
THM_ERROR TimedHashMap<Key, ElementObject>::Insert(const Key& k, const ElementObject& e, const Time& expiry_time)
{
// first, check the size of the hash map to ensure there is room
/*
if ( size_ == MAX_SIZE_ )
{
return E_MAP_IS_FULL;
}
*/
// now, try to put 'e' into the map
try
{
// does k already exist in the hash map?
typename hash_map<Key, BaseElement_*, dw_hash<Key>, dw_equal_to<Key> >::iterator itr;
itr = h_->find(k);
if ( itr != h_->end() )
{
return E_DUPLICATE_KEY;
}
// create a base element object to insert into the timeout queue map
// If the expiry_time is the greatest in queue, insert time is O(1).
// (http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4)
TimeoutQueue_itr_t tq_node;
tq_node = tq_.insert(tq_.end(), make_pair(expiry_time, k));
if (tq_.end() == tq_node)
{
return E_INTERNAL_ERROR;
}
BaseElement_* be = new BaseElement_(e, tq_node);
if ( !be )
{
return E_INTERNAL_ERROR;
}
h_->insert(std::make_pair(k, be));
debugprintfMT(MSGCAT_DEBUG, MSGSUB_OK,"Insert: %x", be);
++size_;
} catch ( ... )
{
return E_INTERNAL_ERROR;
}
// finally assert that the same number of items
// in the queue are in the hash map
if ( size_ != tq_.size() )
{
return E_INTERNAL_ERROR;
}
return E_SUCCESS;
}
Valgrind report is below:
Invalid write of size 1
==3260== at 0x6DECB1E: memcpy (mc_replace_strmem.c:482)
==3260== by 0x804E76E: C_NORTH_WORKER_THREAD::bSaveFragmentResponse(int, int, unsigned char*, unsigned short, VXN_PTR*) (norththread.cpp:1159)
==3260== by 0x805062B: C_NORTH_WORKER_THREAD::ReceiveResponseFromHost(VXN_PTR*&,unsigned char*, unsigned short&) (norththread.cpp:606)
==3260== by 0x8085653: HostWorkerThread::IncomingResponse() (workerthread.cpp:577)
==3260== by 0x80862D7: HostWorkerThread::Main() (workerthread.cpp:255)
==3260== by 0x8086684: HostWorkerThread::SpawnThread(void*) (workerthread.cpp:183)
==3260== by 0x391831: start_thread (in /lib/libpthread-2.5.so)
==3260== by 0x303E0D: clone (in /lib/libc-2.5.so)
==3260== Address 0x7abd894 is 4 bytes inside a block of size 15 free'd
==3260== at 0x6DEA51D: free (vg_replace_malloc.c:325)
==3260== by 0x2B5867: tzset_internal (in /lib/libc-2.5.so)
==3260== by 0x2B616C: tzset (in /lib/libc-2.5.so)
==3260== by 0x2BA8C5: strftime_l (in /lib/libc-2.5.so)
==3260== by 0x2FFFFE: __vsyslog_chk (in /lib/libc-2.5.so)
==3260== by 0x300549: syslog (in /lib/libc-2.5.so)
==3260== by 0x807DBFC: debugprintfMT(int, int, char const*, ...) (hostdefs.cpp:44)
==3260== by 0x805C017: Tracer::Tracer(char const*) (hostdefs.h:167)
==3260== by 0x805C6B9: TimedHashMap<int, FragmentWrapper*>::Find(int const&,FragmentWrapper*&) (timedhashmap.h:389)
==3260== by 0x8051C08: C_NORTH_WORKER_THREAD::SendRequestToHost(VXN_PTR*)(norththread.cpp:318)
==3260== by 0x8085DA4: HostWorkerThread::IncomingRequest(VXN_PTR*)(workerthread.cpp:479)
==3260== by 0x80863B2: HostWorkerThread::Main() (workerthread.cpp:285)
--3260-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--3260-- si_code=1; Faulting address: 0xD8AFF74; sp: 0x4c99dc8
GDB backtrace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xf784a400 (LWP 6549)]
0x0029bc7e in _int_malloc () from /lib/libc.so.6
(gdb)
(gdb)
(gdb)
(gdb)
(gdb)
(gdb) backtrace
#0 0x0029bc7e in _int_malloc () from /lib/libc.so.6
#1 0x0029de97 in malloc () from /lib/libc.so.6
#2 0xf7fb84d7 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
#3 0x0806101d in TimedHashMap<int, std::vector<unsigned char, std::allocator<unsigned char> >*>::Insert (this=0x80b6848, k=@0xf784976c, e=@0xf7849750,
expiry_time=...)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/include/../include/timedhashmap.h:354
#4 0x0804e798 in C_NORTH_WORKER_THREAD::bSaveFragmentResponse (
this=0x80b43a0, s16SessionID=48094, s16MessageID=3,
pResponse=0xf7c56124 "`\003", response_length=48, vxnptr=0x0)
at /home/FBML7HR/SrcCode/vxnservers/fdchost/north/src/norththread.cpp:1167
#5 0x0805062c in C_NORTH_WORKER_THREAD::ReceiveResponseFromHost (
this=0x80b43a0, vxnptr=@0xf784994c, response=0xf7c56124 "`\003",
response_length=@0xf784994a)
at /home/FBML7HR/SrcCode/vxnservers/fdchost/north/src/norththread.cpp:606
#6 0x08085654 in HostWorkerThread::IncomingResponse (this=0xf7c560fc)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/src/workerthread.cpp:577
#7 0x080862d8 in HostWorkerThread::Main (this=0xf7c560fc)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/src/workerthread.cpp:255
#8 0x08086685 in HostWorkerThread::SpawnThread (thread_argument=0xf7c560fc)
at /home/FBML7HR/SrcCode/vxnservers/hostcore/v3/src/workerthread.cpp:183
#9 0x00391832 in start_thread () from /lib/libpthread.so.0
---Type <return> to continue, or q <return> to quit---
#10 0x00303e0e in clone () from /lib/libc.so.6
(gdb)
Any hints would be helpful. Thank you!!
Upvotes: 2
Views: 973
Reputation: 9343
An std::vector
object is not, by itself, a block of memory. It's just some class
or struct
that probably holds a pointer to such a block. You can't therefore copy onto the vector object directly. In order to access its backing memory, use the subscript operator on it:
UCHAR *memBuf = &pResp_Buffer[0];
Then you can use that pointer to access raw memory.
Upvotes: 3