malloc error when using std::shared_ptr - c++

I've decided to parallelize a huge program I wrote and eventually I came across the new C++11 smart pointers.
I had a routine that should be executed many times (usually above 1000 times) that is somewhat expensive. It was ran in a dead simple for loop, what I did was to install this for loop in a method which would be ran by some worker threads.
Did it so, made some parameters wrapped by a std::shared_ptr, cared for race conditions, everything seemed fine.
But now, some times, process will be aborted and I am given one of the following errors:
Process finished with exit code 139 (interrupted by signal 11:
SIGSEGV)
or
malloc.c:2395: sysmalloc: Assertion `(old_top == initial_top (av) &&
old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse
(old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
All of these errors occur while the parallel for is ongoing; not before, not right in the beginning, not in the end, but somewhere in between, which smells me like a race condition not covered.
The program is huge, but I created a miniature of it that is able to reproduce the problem:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <thread>
#include <set>
#include <memory>
#include <atomic>
namespace std {
template <>
struct hash<std::multiset<unsigned long>>
{
std::size_t operator()(const std::multiset<unsigned long>& k) const
{
std::size_t r = 0;
bool shift = false;
for (auto&& it : k) {
r = (r >> !shift) ^ (std::hash<unsigned long>()(it) << shift);
shift = !shift;
}
return r;
}
};
}
typedef std::unordered_map<std::multiset<unsigned long>, int*> graphmap;
std::multiset<unsigned long>* bar(int pos) {
std::multiset<unsigned long> *label = new std::multiset<unsigned long>;
label->insert(pos%5);
label->insert(pos%2);
return label;
}
void foo(std::shared_ptr<graphmap> &kSubgraphs, int pos) {
int *v = (*kSubgraphs)[*bar(pos)];
if(v == nullptr) {
v = new int[pos+1]();
v[0]++;
} else {
v[pos]++;
}
}
void worker(std::shared_ptr<std::atomic_int> *counter, int n, std::shared_ptr<graphmap> *kSubgraphs)
{
for (int pos = (*counter)->fetch_add(1); pos <= n; pos = (*counter)->fetch_add(1)) {
if (pos%100==0) std::cout << pos << std::endl;
foo(*kSubgraphs, pos);
}
}
int main() {
int n = 1000;
std::vector<std::thread> threads;
std::shared_ptr<graphmap> kSubgraphs = std::make_shared<graphmap>();
std::shared_ptr<std::atomic_int> counter = std::make_shared<std::atomic_int>(0);
for (int i=0; i<5; i++) {
foo(kSubgraphs, n);
}
for (int i=0; i<4; i++) {
threads.push_back(std::thread(worker, &counter, n, &kSubgraphs));
}
for(auto& th : threads) th.join();
return 0;
}
This code basically mimics the behavior of the original code, which is to use an unordered_map keyed by a multiset with values that are pointers to int arrays. First some keys are inserted and the array initialized (maybe the problem is caused by the way I am initializing it?) and finally the worker threads run to update a unique position of the array of an entry of the unordered_map.
Two threads may access the same map entry simultaneously, but they will never write to the same index of the array at the same time.
Different from the original code, this code won't throw any errors when running over internet compilers such as ideone.com, I also tried to run it from CLion ide and no errors will occur (maybe it can occur errors if one tries enough times), but I got similar error as the original when running from the command line multiple times. I compiled it with:
g++ -std=c++11 -pthread -o test.exe test.cpp
And after running several times it eventually gives this error:
*** Error in `./test.exe': double free or corruption (fasttop): 0x00000000006a2d30 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7fccc9d4f725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7fccc9d57f4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fccc9d5babc]
./test.exe[0x404e9e]
./test.exe[0x40431b]
./test.exe[0x4045ed]
./test.exe[0x407c6c]
./test.exe[0x4078d6]
./test.exe[0x40742a]
./test.exe[0x40869e]
./test.exe[0x4086be]
./test.exe[0x4085dd]
./test.exe[0x40842d]
./test.exe[0x4023a2]
./test.exe[0x401d55]
./test.exe[0x401c4a]
./test.exe[0x401c66]
./test.exe[0x401702]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fccc9cf8830]
./test.exe[0x401199]
======= Memory map: ========
00400000-0040f000 r-xp 00000000 08:05 12202697 /home/rodrigo/test.exe
0060e000-0060f000 r--p 0000e000 08:05 12202697 /home/rodrigo/test.exe
0060f000-00610000 rw-p 0000f000 08:05 12202697 /home/rodrigo/test.exe
00691000-006c3000 rw-p 00000000 00:00 0 [heap]
7fcca8000000-7fcca8089000 rw-p 00000000 00:00 0
7fcca8089000-7fccac000000 ---p 00000000 00:00 0
7fccb0000000-7fccb008b000 rw-p 00000000 00:00 0
7fccb008b000-7fccb4000000 ---p 00000000 00:00 0
7fccb8000000-7fccb8089000 rw-p 00000000 00:00 0
7fccb8089000-7fccbc000000 ---p 00000000 00:00 0
7fccc0000000-7fccc007c000 rw-p 00000000 00:00 0
7fccc007c000-7fccc4000000 ---p 00000000 00:00 0
7fccc79cb000-7fccc79cc000 ---p 00000000 00:00 0
7fccc79cc000-7fccc81cc000 rw-p 00000000 00:00 0
7fccc81cc000-7fccc81cd000 ---p 00000000 00:00 0
7fccc81cd000-7fccc89cd000 rw-p 00000000 00:00 0
7fccc89cd000-7fccc89ce000 ---p 00000000 00:00 0
7fccc89ce000-7fccc91ce000 rw-p 00000000 00:00 0
7fccc91ce000-7fccc91cf000 ---p 00000000 00:00 0
7fccc91cf000-7fccc99cf000 rw-p 00000000 00:00 0
7fccc99cf000-7fccc9ad7000 r-xp 00000000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9ad7000-7fccc9cd6000 ---p 00108000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9cd6000-7fccc9cd7000 r--p 00107000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9cd7000-7fccc9cd8000 rw-p 00108000 08:05 24126366 /lib/x86_64-linux-gnu/libm-2.23.so
7fccc9cd8000-7fccc9e98000 r-xp 00000000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccc9e98000-7fccca097000 ---p 001c0000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccca097000-7fccca09b000 r--p 001bf000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccca09b000-7fccca09d000 rw-p 001c3000 08:05 24126374 /lib/x86_64-linux-gnu/libc-2.23.so
7fccca09d000-7fccca0a1000 rw-p 00000000 00:00 0
7fccca0a1000-7fccca0b9000 r-xp 00000000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca0b9000-7fccca2b8000 ---p 00018000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca2b8000-7fccca2b9000 r--p 00017000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca2b9000-7fccca2ba000 rw-p 00018000 08:05 24126373 /lib/x86_64-linux-gnu/libpthread-2.23.so
7fccca2ba000-7fccca2be000 rw-p 00000000 00:00 0
7fccca2be000-7fccca2d4000 r-xp 00000000 08:05 24121519 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fccca2d4000-7fccca4d3000 ---p 00016000 08:05 24121519 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fccca4d3000-7fccca4d4000 rw-p 00015000 08:05 24121519 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fccca4d4000-7fccca646000 r-xp 00000000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca646000-7fccca846000 ---p 00172000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca846000-7fccca850000 r--p 00172000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca850000-7fccca852000 rw-p 0017c000 08:05 6029347 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fccca852000-7fccca856000 rw-p 00000000 00:00 0
7fccca856000-7fccca87c000 r-xp 00000000 08:05 24126370 /lib/x86_64-linux-gnu/ld-2.23.so
7fcccaa44000-7fcccaa4a000 rw-p 00000000 00:00 0
7fcccaa78000-7fcccaa7b000 rw-p 00000000 00:00 0
7fcccaa7b000-7fcccaa7c000 r--p 00025000 08:05 24126370 /lib/x86_64-linux-gnu/ld-2.23.so
7fcccaa7c000-7fcccaa7d000 rw-p 00026000 08:05 24126370 /lib/x86_64-linux-gnu/ld-2.23.so
7fcccaa7d000-7fcccaa7e000 rw-p 00000000 00:00 0
7ffc6b1c8000-7ffc6b1e9000 rw-p 00000000 00:00 0 [stack]
7ffc6b1fa000-7ffc6b1fc000 r--p 00000000 00:00 0 [vvar]
7ffc6b1fc000-7ffc6b1fe000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[1] 26639 abort (core dumped) ./test.exe
At last, when running the original code with debug mode on in CLion set up to capture Exceptions as breakpoints, it shows a Signal interruption of SIGBUS(Bus error) or a SIGSEGV(Segmentation fault) sometimes and last line of code executed before the interruption maps to the line:
int *v = (*kSubgraphs)[*bar(pos)];
in the foo function of the code presented here.
I am a little bit lost with this one. My strongest assumption is that I am using smart pointers the wrong way, despite I do not see where.

Your program has undefined behavior, because you access the object pointed to by kSubgraphs from different threads without mutual exclusion. This happens in this line of code in function foo, which is called from your thread function worker:
int *v = (*kSubgraphs)[*bar(pos)];
I can't guess why you think shared_ptr would help your case in any way. The way you do, it is totally pointless to wrap your objects in shared_ptr.
shared_ptr is used when ownership of your objects is shared from different other objects. It has nothing to do with "sharing objects between threads".

Related

std::unordered_map throws seg fault when inserting a specific key

I have a python code base that sometimes invokes C++ programs to handle intensive workloads. One such code has to count all kmers of a certain size in a large text file. For each line it reads, it creates a temporary index that stores the position of each kmer. Here is the function that processes each line:
void process_read(char* read, int num) {
int l = strlen(read) ;
std::string seq(read) ;
// index kmers
std::unordered_map<std::string, std::vector<int>> index ;
for (int i = 0 ; i <= l - 1 - 15 ; i++) {
std::string k = seq.substr(i, 15) ;
if (global_index->find(k) == global_index->end()) {
continue ;
}
if (index.find(k) == index.end()) {
index.insert(std::make_pair(k, std::vector<int>(1, i))) ;
} else {
index[k].push_back(i) ;
}
}
// 50+ lines of code commented out. It returns here
}
The code crashes every time it reaches a certain line of input:
ACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCAAACCATAACCCTAAACCTCACGATAACCCAAACCATCACCAAAAAAAAAAAAAACACACCTACCGAAACCAACAACATA
Out of the kmers in this line, only AAAAAAAAAAAAAAC and CAAAAAAAAAAAAAA make it to index. The code always crashes when trying to insert CAAAAAAAAAAAAAA for some reason I don't understand. I guess is a problem with these keys being inserted into the unordered_map in sequence. Changing the function to this will still result in the same crash when inserting the second key:
void process_read(char* read, int num) {
std::unordered_map<std::string, std::vector<int>> index ;
index.insert(std::make_pair("AAAAAAAAAAAAAAC", std::vector<int>(1, 2))) ;
index.insert(std::make_pair("CAAAAAAAAAAAAAA", std::vector<int>(1, 2))) ;
}
Now this function is clearly not accessing any global state unlike the original one so the problem has to be with these specific keys (notice that one is a circular shift of the other, the hash function used might not be comfortable with that); however, putting this code at the start of the program or writing another small program that only does this doesn't seem to reproduce the crash so I'm really confused.
Any suggestion is appreciated.
Update:
I get this stack trace during the crash. For reasons, I can't use gdb to debug so I guess this is the best I'm going to get. But don't know how to interpret it.
*** Error in `src/python/kmer/c_counter.out': malloc(): memory corruption (fast): 0x0000000001eac690 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f189daa47e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82651)[0x7f189daaf651]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f189dab1184]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_Znwm+0x18)[0x7f189e3a3e78]
/src/python/kmer/c_counter.out[0x41c5e4]
/src/python/kmer/c_counter.out[0x4146ea]
/src/python/kmer/c_counter.out[0x41453a]
/src/python/kmer/c_counter.out[0x41035b]
/src/python/kmer/c_counter.out[0x40b3d8]
/src/python/kmer/c_counter.out[0x40940a]
/src/python/kmer/c_counter.out[0x404528]
/src/python/kmer/c_counter.out[0x404f9d]
/src/python/kmer/c_counter.out[0x405f42]
/src/python/kmer/c_counter.out[0x4063d6]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f189da4d830]
/src/python/kmer/c_counter.out[0x403b39]
======= Memory map: ========
00400000-00440000 r-xp 00000000 00:2f 546796 src/python/kmer/c_counter.out
0063f000-00640000 rw-p 0003f000 00:2f 546796 src/python/kmer/c_counter.out
014a0000-01ebf000 rw-p 00000000 00:00 0 [heap]
7f1898000000-7f1898021000 rw-p 00000000 00:00 0
7f1898021000-7f189c000000 ---p 00000000 00:00 0
7f189da2d000-7f189dbed000 r-xp 00000000 fc:00 1439150 /lib/x86_64-linux-gnu/libc-2.23.so
7f189dbed000-7f189dded000 ---p 001c0000 fc:00 1439150 /lib/x86_64-linux-gnu/libc-2.23.so
7f189dded000-7f189ddf1000 r--p 001c0000 fc:00 1439150 /lib/x86_64-linux-gnu/libc-2.23.so
7f189ddf1000-7f189ddf3000 rw-p 001c4000 fc:00 1439150 /lib/x86_64-linux-gnu/libc-2.23.so
7f189ddf3000-7f189ddf7000 rw-p 00000000 00:00 0
7f189ddf7000-7f189de0d000 r-xp 00000000 fc:00 1439041 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f189de0d000-7f189e00c000 ---p 00016000 fc:00 1439041 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f189e00c000-7f189e00d000 rw-p 00015000 fc:00 1439041 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f189e00d000-7f189e115000 r-xp 00000000 fc:00 1439141 /lib/x86_64-linux-gnu/libm-2.23.so
7f189e115000-7f189e314000 ---p 00108000 fc:00 1439141 /lib/x86_64-linux-gnu/libm-2.23.so
7f189e314000-7f189e315000 r--p 00107000 fc:00 1439141 /lib/x86_64-linux-gnu/libm-2.23.so
7f189e315000-7f189e316000 rw-p 00108000 fc:00 1439141 /lib/x86_64-linux-gnu/libm-2.23.so
7f189e316000-7f189e488000 r-xp 00000000 fc:00 671990 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e488000-7f189e688000 ---p 00172000 fc:00 671990 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e688000-7f189e692000 r--p 00172000 fc:00 671990 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e692000-7f189e694000 rw-p 0017c000 fc:00 671990 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e694000-7f189e698000 rw-p 00000000 00:00 0
7f189e698000-7f189e6be000 r-xp 00000000 fc:00 1439146 /lib/x86_64-linux-gnu/ld-2.23.so
7f189e878000-7f189e89f000 rw-p 00000000 00:00 0
7f189e8bc000-7f189e8bd000 rw-p 00000000 00:00 0
7f189e8bd000-7f189e8be000 r--p 00025000 fc:00 1439146 /lib/x86_64-linux-gnu/ld-2.23.so
7f189e8be000-7f189e8bf000 rw-p 00026000 fc:00 1439146 /lib/x86_64-linux-gnu/ld-2.23.so
7f189e8bf000-7f189e8c0000 rw-p 00000000 00:00 0
7ffea4907000-7ffea4929000 rw-p 00000000 00:00 0 [stack]
7ffea49b6000-7ffea49b9000 r--p 00000000 00:00 0 [vvar]
7ffea49b9000-7ffea49bb000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Changing the function to this will still result in the same crash when inserting the second key:
[...]
putting this code at the start of the program or writing another small program that only does this doesn't seem to reproduce the crash so I'm really confused.
std::unordered_map has no relevant global state that could change between "everything is fine if I run this test function at the start" and "if I run this test function later, the map crashes". You have memory corruption due to undefined behavior somewhere else in your program - the observations you made are the strongest proof you could get for that.
The function signature suggests that you don't necessarily have a null ended string(one that has a \0 as the last character).
But you don't treat it as such(you should use variants that take num as a parameter). I suspect this pattern repeats in other places and at some point you corrupt your memory.
If I were you i would build the binary with Valgrind or some other memory analysis tool and run it again. It will catch the incorrect access where it happens.
The way you use unordered_map looks fine to me.

Unexplainable VIRTUAL memory behavior for multi-threading code heap allocation

I am trying to study the effect of pthread based Multi-threading code modifications on VIRTUAL memory on a 64-bit Centos based Linux system
I am attaching a spreadsheet where the observations were made on VIRTUAL MEMORY (using Linux based top command) with increasing the number of threads and each thread is allocating 1MB each.
I am pasting C++ code used for observation (below) for the reference:
From the observations made shown in the table below, for a single thread allocating 1MB data VIRTUAL memory used is 89.824MB, for 2 threads allocating 1MB each VIRTUAL memory is 165.604MB, for 3 threads allocating 1MB each VIRTUAL memory is 235MB and then onwards VIRTUAL memory increases by 1MB per thread.
Click here to view the table having observations made
To summarize, VIRTUAL memory starts with 89MB, becomes double after adding 2nd thread, again becomes almost double after adding 3rd thread, then increases by 1MB for addition of each thread, each allocating 1MB of heap.
Can anyone explain why is this behavior exhibited by the system ?
Please post if you need any other details. Looking forward for the help.
Note:
the code was compiled using g++ (g++ -o vma CODE_FILE.cpp -lpthread)
only 1MB of heap was allocated by each thread but were not populated
the generated binary size is only ~9KB (got using ls command)
#include <iostream>
#include <pthread.h>
using namespace std;
/*
NOTE: Make sure you provide NUM_THREADS in the range (1..5)
*/
#define NUM_THREADS 5
struct thread_struct
{
int id;
char *msg;
};
void *thrdFunc(void *i)
{
char *it = (char*)i;
cout << "\nthis is thread named :"<< it ;
char *mallocBlk = new char [1000000];
}
int main()
{
int rc = 0;
void *status;
char threadNames[8][8] = { "Thread1" , "Thread2", "Thread3", "Thread4", "Thread5", "Thread6", "Thread7", "Thread8"};
pthread_t threads[NUM_THREADS];
thread_struct thrStructs[NUM_THREADS];
cout << "\nIn Main, creating threads!" ;
/*
Create threads
*/
for (int i = 0; i < NUM_THREADS; i++)
{
rc = pthread_create(&threads[i], NULL, thrdFunc, &threadNames[i] );
if (rc)
{
cout << "Thrd" << i+1 << " cant be created";
}
}
/*
Wait till all the threads complete
*/
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], &status);
}
cout << endl;
cout << "Done! Waiting for your input!";
cin.get();
return 0;
}
Below is the memory map for 5 threads:
[rebaca#localhost stackoverflow]$ cat /proc/31528/maps
00400000-00401000 r-xp 00000000 fd:02 20451094 /home/rebaca/stackoverflow/vma
00601000-00602000 rw-p 00001000 fd:02 20451094 /home/rebaca/stackoverflow/vma
01784000-017a5000 rw-p 00000000 00:00 0 [heap]
305b400000-305b420000 r-xp 00000000 fd:00 1703944 /lib64/ld-2.12.so
305b61f000-305b620000 r--p 0001f000 fd:00 1703944 /lib64/ld-2.12.so
305b620000-305b621000 rw-p 00020000 fd:00 1703944 /lib64/ld-2.12.so
305b621000-305b622000 rw-p 00000000 00:00 0
305b800000-305b98a000 r-xp 00000000 fd:00 1703966 /lib64/libc-2.12.so
305b98a000-305bb8a000 ---p 0018a000 fd:00 1703966 /lib64/libc-2.12.so
305bb8a000-305bb8e000 r--p 0018a000 fd:00 1703966 /lib64/libc-2.12.so
305bb8e000-305bb90000 rw-p 0018e000 fd:00 1703966 /lib64/libc-2.12.so
305bb90000-305bb94000 rw-p 00000000 00:00 0
305bc00000-305bc17000 r-xp 00000000 fd:00 1703968 /lib64/libpthread-2.12.so
305bc17000-305be17000 ---p 00017000 fd:00 1703968 /lib64/libpthread-2.12.so
305be17000-305be18000 r--p 00017000 fd:00 1703968 /lib64/libpthread-2.12.so
305be18000-305be19000 rw-p 00018000 fd:00 1703968 /lib64/libpthread-2.12.so
305be19000-305be1d000 rw-p 00000000 00:00 0
305c800000-305c883000 r-xp 00000000 fd:00 1704110 /lib64/libm-2.12.so
305c883000-305ca82000 ---p 00083000 fd:00 1704110 /lib64/libm-2.12.so
305ca82000-305ca83000 r--p 00082000 fd:00 1704110 /lib64/libm-2.12.so
305ca83000-305ca84000 rw-p 00083000 fd:00 1704110 /lib64/libm-2.12.so
3066800000-3066816000 r-xp 00000000 fd:00 1704139 /lib64/libgcc_s-4.4.7-20120601.so.1
3066816000-3066a15000 ---p 00016000 fd:00 1704139 /lib64/libgcc_s-4.4.7-20120601.so.1
3066a15000-3066a16000 rw-p 00015000 fd:00 1704139 /lib64/libgcc_s-4.4.7-20120601.so.1
3066c00000-3066ce8000 r-xp 00000000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066ce8000-3066ee8000 ---p 000e8000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066ee8000-3066eef000 r--p 000e8000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066eef000-3066ef1000 rw-p 000ef000 fd:00 809560 /usr/lib64/libstdc++.so.6.0.13
3066ef1000-3066f06000 rw-p 00000000 00:00 0
7fd3ec000000-7fd3ec115000 rw-p 00000000 00:00 0
7fd3ec115000-7fd3f0000000 ---p 00000000 00:00 0
7fd3f0000000-7fd3f0115000 rw-p 00000000 00:00 0
7fd3f0115000-7fd3f4000000 ---p 00000000 00:00 0
7fd3f4000000-7fd3f4115000 rw-p 00000000 00:00 0
7fd3f4115000-7fd3f8000000 ---p 00000000 00:00 0
7fd3f8000000-7fd3f8115000 rw-p 00000000 00:00 0
7fd3f8115000-7fd3fc000000 ---p 00000000 00:00 0
7fd3fc000000-7fd3fc115000 rw-p 00000000 00:00 0
7fd3fc115000-7fd400000000 ---p 00000000 00:00 0
7fd4032b6000-7fd4032b7000 ---p 00000000 00:00 0
7fd4032b7000-7fd403cb7000 rw-p 00000000 00:00 0
7fd403cb7000-7fd403cb8000 ---p 00000000 00:00 0
7fd403cb8000-7fd4046b8000 rw-p 00000000 00:00 0
7fd4046b8000-7fd4046b9000 ---p 00000000 00:00 0
7fd4046b9000-7fd4050b9000 rw-p 00000000 00:00 0
7fd4064bb000-7fd4064c1000 rw-p 00000000 00:00 0
7fd4064db000-7fd4064de000 rw-p 00000000 00:00 0
7ffc72456000-7ffc7246b000 rw-p 00000000 00:00 0 [stack]
7ffc72568000-7ffc72569000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

Getting a free(): invalid pointer error

I was trying to make a program that replaces characters e with * on a string that has the most e's,but I'm getting a random free(): invalid pointer error whenever I run this program:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
const char char1 = 'e', char2 = '*';
int N, mostchars = 0, its;
cout << "N = ";
cin >> N;
string strings[N];
for(int i = 1; i <= N; i++)
{
cin >> strings[i];
if(mostchars < count(strings[i].begin(), strings[i].end(), char1))
{
mostchars = count(strings[i].begin(), strings[i].end(), char1);
its = i;
}
}
replace(strings[its].begin(), strings[its].end(), char1, char2);
cout << strings[its] << endl;
return 0;
}
And here's the gdb output:
*** Error in `/home/hiddendirishidden/STRING/bin/Debug/STRING': free(): invalid pointer: 0x00007fffffffe6a0 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x6f364)[0x7ffff720a364]
/usr/lib/libc.so.6(+0x74d96)[0x7ffff720fd96]
/usr/lib/libc.so.6(+0x7557e)[0x7ffff721057e]
/usr/lib/libstdc++.so.6(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm+0xfd)[0x7ffff7b765dd]
/usr/lib/libstdc++.so.6(_ZStrsIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_stringIS4_S5_T1_EE+0x314)[0x7ffff7afd624]
/home/hiddendirishidden/STRING/bin/Debug/STRING[0x400e13]
/usr/lib/libc.so.6(__libc_start_main+0xf0)[0x7ffff71bb710]
/home/hiddendirishidden/STRING/bin/Debug/STRING[0x400c39]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:21 1452363 /home/hiddendirishidden/STRING/bin/Debug/STRING
00601000-00602000 rw-p 00001000 08:21 1452363 /home/hiddendirishidden/STRING/bin/Debug/STRING
00602000-00634000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff719b000-7ffff7333000 r-xp 00000000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7333000-7ffff7532000 ---p 00198000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7532000-7ffff7536000 r--p 00197000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7536000-7ffff7538000 rw-p 0019b000 08:21 396432 /usr/lib/libc-2.23.so
7ffff7538000-7ffff753c000 rw-p 00000000 00:00 0
7ffff753c000-7ffff7552000 r-xp 00000000 08:21 396763 /usr/lib/libgcc_s.so.1
7ffff7552000-7ffff7751000 ---p 00016000 08:21 396763 /usr/lib/libgcc_s.so.1
7ffff7751000-7ffff7752000 rw-p 00015000 08:21 396763 /usr/lib/libgcc_s.so.1
7ffff7752000-7ffff7855000 r-xp 00000000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7855000-7ffff7a55000 ---p 00103000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7a55000-7ffff7a56000 r--p 00103000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7a56000-7ffff7a57000 rw-p 00104000 08:21 396490 /usr/lib/libm-2.23.so
7ffff7a57000-7ffff7bc9000 r-xp 00000000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7bc9000-7ffff7dc9000 ---p 00172000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7dc9000-7ffff7dd3000 r--p 00172000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7dd3000-7ffff7dd5000 rw-p 0017c000 08:21 396798 /usr/lib/libstdc++.so.6.0.21
7ffff7dd5000-7ffff7dd9000 rw-p 00000000 00:00 0
7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:21 396431 /usr/lib/ld-2.23.so
7ffff7fc5000-7ffff7fcb000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ff8000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:21 396431 /usr/lib/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:21 396431 /usr/lib/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGABRT, Aborted.
0x00007ffff71ce2a8 in raise () from /usr/lib/libc.so.6
I'm not sure why that happens. Maybe I did something wrong, after all this is the first time I'm trying out the algorithm library.
In
for(int i = 1; i <= N; i++)
You are using 1-based index. strings only has elements indexed from 0 to N-1, strings[N] is an invalid access.
C++ convention is 0-based indexes. Do
for(int i = 0; i < N; ++i)
You also may like to initialize variables and check for errors on input.
You used a variable to determine the length of an array. You cannot do this safely in C++.
Use std::vector<std::string> instead of std::string[N].
Furthermore, your loop goes 1 → N, instead of the correct 0 → N-1. That means the std::string you're trying to access on the final iteration doesn't exist, and the various allocations that the std::string performs internally are therefore broken.

trash output when run a std:: vector<double> code in linux terminal - C++

I am trying to make a simple std::vector code on C++ with g++ on linux terminal but confused with the output on the terminal itself.
My code is simple.
#include <iostream>
#include <vector>
int main() {
double xl;
int nx=5;
double delta_x;
int i=0;
std::vector<double> x(nx);
for(i=0; i <=nx; i++) {
x[i]=0.0005;
std::cout<<x[i]<<std::endl;
}
return 0;
}
when I compile:
$ g++ grid2.cpp -o grid2
It succeeded and gives a grid2 executable. The problem arise when I run the executable:
$ ./grid2
gives me output like this on the terminal:
./grid2[0x400929]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:05 13372783 /mnt/home/FINALS/codeDNS_AKA_MY_MAIN_DIR/basic_CPP/grid2
00601000-00602000 rw-p 00001000 08:05 13372783 /mnt/home/FINALS/codeDNS_AKA_MY_MAIN_DIR/basic_CPP/grid2
01f23000-01f55000 rw-p 00000000 00:00 0 [heap]
7f13fc000000-7f13fc021000 rw-p 00000000 00:00 0
7f13fc021000-7f1400000000 ---p 00000000 00:00 0
7f1403971000-7f1403b0c000 r-xp 00000000 08:06 790319 /usr/lib/libc-2.22.so
7f1403b0c000-7f1403d0b000 ---p 0019b000 08:06 790319 /usr/lib/libc-2.22.so
7f1403d0b000-7f1403d0f000 r--p 0019a000 08:06 790319 /usr/lib/libc-2.22.so
7f1403d0f000-7f1403d11000 rw-p 0019e000 08:06 790319 /usr/lib/libc-2.22.so
7f1403d11000-7f1403d15000 rw-p 00000000 00:00 0
7f1403d15000-7f1403d2b000 r-xp 00000000 08:06 790384 /usr/lib/libgcc_s.so.1
7f1403d2b000-7f1403f2a000 ---p 00016000 08:06 790384 /usr/lib/libgcc_s.so.1
7f1403f2a000-7f1403f2b000 rw-p 00015000 08:06 790384 /usr/lib/libgcc_s.so.1
7f1403f2b000-7f1404028000 r-xp 00000000 08:06 790449 /usr/lib/libm-2.22.so
7f1404028000-7f1404227000 ---p 000fd000 08:06 790449 /usr/lib/libm-2.22.so
7f1404227000-7f1404228000 r--p 000fc000 08:06 790449 /usr/lib/libm-2.22.so
7f1404228000-7f1404229000 rw-p 000fd000 08:06 790449 /usr/lib/libm-2.22.so
7f1404229000-7f140439b000 r-xp 00000000 08:06 790552 /usr/lib/libstdc++.so.6.0.21
7f140439b000-7f140459b000 ---p 00172000 08:06 790552 /usr/lib/libstdc++.so.6.0.21
7f140459b000-7f14045a5000 r--p 00172000 08:06 790552 /usr/lib/libstdc++.so.6.0.21
7f14045a5000-7f14045a7000 rw-p 0017c000 08:06 790552 /usr/lib/libstdc++.so.6.0.21
7f14045a7000-7f14045ab000 rw-p 00000000 00:00 0
7f14045ab000-7f14045cd000 r-xp 00000000 08:06 790282 /usr/lib/ld-2.22.so
7f1404791000-7f1404797000 rw-p 00000000 00:00 0
7f14047ca000-7f14047cc000 rw-p 00000000 00:00 0
7f14047cc000-7f14047cd000 r--p 00021000 08:06 790282 /usr/lib/ld-2.22.so
7f14047cd000-7f14047ce000 rw-p 00022000 08:06 790282 /usr/lib/ld-2.22.so
7f14047ce000-7f14047cf000 rw-p 00000000 00:00 0
7ffec8a9b000-7ffec8abc000 rw-p 00000000 00:00 0 [stack]
7ffec8bef000-7ffec8bf1000 r--p 00000000 00:00 0 [vvar]
7ffec8bf1000-7ffec8bf3000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
But the (another) weird thing is, when I change the
std::vector<double>
into
std::vector<float>
Those trash are all gone. And I can see the clean output right on my terminal.
And the other thing, when I print the output to another file like this:
$ ./grid2 > test.txt
the results are the same for both double and float. No trash, clean output. It's like the trash only appear on my terminal.
I am novice on linux and c++, so please if anyone know what I'm facing, I'll be very happy to hear that :)
As already noted, you have undefined behavior.
Although changing the <= to < does work, it just makes this code correct. It doesn't "immunize" you against running into essentially the same problem again soon.
One alternative would be to use the "range-based" for loop like this:
#include <iostream>
#include <vector>
int main() {
double xl;
int nx=5;
double delta_x;
int i=0;
std::vector<double> x(nx);
for(double &d : x) {
d=0.0005;
std::cout<<d<<"\n";
}
}
Though in this case, you're filling it with all identical values, so it's probably better to just initialize it that way:
#include <iostream>
#include <vector>
int main() {
std::vector<double> x(5, 0.0005);
for (double const &d : x)
std::cout << d << "\n";
}
The range-based for loop makes it much more difficult to accidentally attempt to access outside the bounds of the collection.
As an aside: note the use of "\n" instead of std::endl. I would recommend against using std::endl in general--on the rare occasion that you need what it does, make that explicit with std::cout << "\n" << std::flush;. In the much more common case that you didn't really want that flush, just omit it. endl does both, even though the flush is almost never desired (and most people aren't aware it even happens).
x has 5 elements. Unfortunately you are accessing 6 - your for loop gives i values from 0 to 5 inclusive, which is a total of 6. Accessing x[5] is undefined behaviour; if you're lucky it crashes in an obvious way, but anything could happen.
You either need to make x bigger, or write your loop as
for(i=0; i < nx; i++)
(using < rather than <=).

Weird stack smash error - caused by unused, uninitialized member variable

Today I had a fun bug where apparently my stack got smashed, overriding the G++ return-point canary (I think that's the protection used).
My offending class was this:
class ClientSendContext : public SendContext
{
public:
ClientSendContext(UdpClient& client);
void send(boost::asio::const_buffer buffer);
private:
boost::asio::ip::udp::endpoint endpoint;
UdpClient& client;
};
The thing was, the client variable was initialized in the initializer list, but not the endpoint (it's not used in the ClientSendContext, since it only sends to one endpoint, but no matter). The smash-stack occured once every three times I executed my test (or something like that) which is weird, since I do the exact same thing (must be thread timing issue).
However, as soon I remove the endpoint variable, it works fine! How can this be? It wasn't used in any way, g++ didn't warn me about it... Valgrind was quiet aswell.
(Could someone with high rep please edit my question and add stack-smash or something like that as a tag?)
Alright, an update with more code, posted on pastebin:
http://pastebin.com/xiWx8xjV
That should be all the methods called. The inner most send method is part of a templated class. The same send method works fine when the UdpServer uses it.. I'm just a bit stumped right now.
EDIT: Code now put directly here:
void doTest(bool& failed)
{
ReceiveHelper helper(failed);
boost::threadpool::pool pool(2);
int port = 55600;
boost::asio::io_service service;
udp::endpoint thisPoint = udp::endpoint(address::from_string("127.0.0.1"),
port);
udp::endpoint receivePoint;
udp::socket socket(service, thisPoint);
socket.async_receive_from(boost::asio::buffer(helper.buffer), receivePoint, boost::bind(&ReceiveHelper::handleReceive,
&helper, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
pool.schedule(boost::bind(&boost::asio::io_service::run, &service));
voip::network::client::UdpClient client;
client.connect(thisPoint);
client.send(1, "Hello!");
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
service.stop();
}
class ReceiveHelper {
private:
bool& failed;
public:
ReceiveHelper(bool & failed) : failed(failed), buffer()
{
}
boost::array<uint8_t, BUF_SIZE> buffer;
void handleReceive(const boost::system::error_code & error, size_t numBytes)
{
if(numBytes != 8)
return;
if(std::string((char*)buffer.c_array(), 6) != "Hello!")
return;
failed = false;
}
};
void UdpClient::send(uint8_t handler, std::string message)
{ <-------------------------------------------------------------------------------------- Canary at this point fails
ClientSendContext context(*this);
ClientConnection::send(context, handler, message);
} <-------------------------------------------------------------------------------------- Canary at this point fails
void send(SendContext & sendContext, uint8_t handler, std::string & message)
{
uint8_t *array = new uint8_t[message.size() + 2];
memcpy(array, message.c_str(), message.size());
boost::asio::mutable_buffer buffer(array, message.size() + 2);
prepareMessage(handler, buffer);
sendContext.send(buffer);
delete[] array;
}
size_t prepareMessage(uint8_t handler, boost::asio::mutable_buffer message)
{
size_t messageLength = boost::asio::buffer_size(message);
uint8_t* data = boost::asio::buffer_cast<uint8_t*>(message);
data[messageLength - 1] = network::handler;
data[messageLength - 2] = handler;
return messageLength;
}
And the error message:
*** stack smashing detected ***: ./testclient terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x37)[0x58e9537]
/lib/libc.so.6(__fortify_fail+0x0)[0x58e9500]
./testclient(_ZN4voip7network6client9UdpClient4sendEhSs+0x85)[0x46b449]
./testclient(_ZN4voip4test6client18SuiteTestUdpClient6doTestERb+0x2dd)[0x44c7c1]
./testclient(_ZNK4voip4test6client18SuiteTestUdpClient17TestClientCanSend7RunImplEv+0x2f)[0x44c957]
./testclient(_ZN8UnitTest11ExecuteTestINS_4TestEEEvRT_RKNS_11TestDetailsE+0x9a)[0x469551]
./testclient(_ZN8UnitTest4Test3RunEv+0x23)[0x46920f]
./testclient(_ZNK8UnitTest10TestRunner7RunTestEPNS_11TestResultsEPNS_4TestEi+0x7c)[0x469b74]
./testclient(_ZNK8UnitTest10TestRunner10RunTestsIfINS_4TrueEEEiRKNS_8TestListEPKcRKT_i+0x8f)[0x469ddb]
./testclient(_ZN8UnitTest11RunAllTestsEv+0x53)[0x4697b7]
./testclient(main+0x9)[0x44ca62]
/lib/libc.so.6(__libc_start_main+0xfe)[0x5808d8e]
./testclient[0x44c429]
======= Memory map: ========
00400000-00494000 r-xp 00000000 08:05 150971 /home/max/Documents/c++proj/voip/build/testclient
00693000-00694000 r--p 00093000 08:05 150971 /home/max/Documents/c++proj/voip/build/testclient
00694000-00695000 rw-p 00094000 08:05 150971 /home/max/Documents/c++proj/voip/build/testclient
00695000-00696000 rw-p 00000000 00:00 0
04000000-04020000 r-xp 00000000 08:05 560792 /lib/ld-2.12.1.so
04020000-04022000 rw-p 00000000 00:00 0
0403f000-04045000 rw-p 00000000 00:00 0
04220000-04221000 r--p 00020000 08:05 560792 /lib/ld-2.12.1.so
04221000-04222000 rw-p 00021000 08:05 560792 /lib/ld-2.12.1.so
04222000-04223000 rw-p 00000000 00:00 0
04223000-04224000 rwxp 00000000 00:00 0
04a23000-04a24000 r-xp 00000000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04a24000-04c23000 ---p 00001000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04c23000-04c24000 r--p 00000000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04c24000-04c25000 rw-p 00001000 08:05 145700 /usr/lib/valgrind/vgpreload_core-amd64-linux.so
04c25000-04c2d000 r-xp 00000000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04c2d000-04e2c000 ---p 00008000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04e2c000-04e2d000 r--p 00007000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04e2d000-04e2e000 rw-p 00008000 08:05 145715 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
04e2e000-04e46000 r-xp 00000000 08:05 557639 /lib/libpthread-2.12.1.so
04e46000-05045000 ---p 00018000 08:05 557639 /lib/libpthread-2.12.1.so
05045000-05046000 r--p 00017000 08:05 557639 /lib/libpthread-2.12.1.so
05046000-05047000 rw-p 00018000 08:05 557639 /lib/libpthread-2.12.1.so
05047000-0504b000 rw-p 00000000 00:00 0
0504b000-05133000 r-xp 00000000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
05133000-05332000 ---p 000e8000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
05332000-0533a000 r--p 000e7000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
0533a000-0533c000 rw-p 000ef000 08:05 656172 /usr/lib/libstdc++.so.6.0.14
0533c000-05351000 rw-p 00000000 00:00 0
05351000-053d3000 r-xp 00000000 08:05 560787 /lib/libm-2.12.1.so
053d3000-055d2000 ---p 00082000 08:05 560787 /lib/libm-2.12.1.so
055d2000-055d3000 r--p 00081000 08:05 560787 /lib/libm-2.12.1.so
055d3000-055d4000 rw-p 00082000 08:05 560787 /lib/libm-2.12.1.so
055d4000-055e9000 r-xp 00000000 08:05 521495 /lib/libgcc_s.so.1
055e9000-057e8000 ---p 00015000 08:05 521495 /lib/libgcc_s.so.1
057e8000-057e9000 r--p 00014000 08:05 521495 /lib/libgcc_s.so.1
057e9000-057ea000 rw-p 00015000 08:05 521495 /lib/libgcc_s.so.1
057ea000-05964000 r-xp 00000000 08:05 557476 /lib/libc-2.12.1.so
05964000-05b63000 ---p 0017a000 08:05 557476 /lib/libc-2.12.1.so
05b63000-05b67000 r--p 00179000 08:05 557476 /lib/libc-2.12.1.so
05b67000-05b68000 rw-p 0017d000 08:05 557476 /lib/libc-2.12.1.so
05b68000-05b6d000 rw-p 00000000 00:00 0
05b6d000-05f6d000 rwxp 00000000 00:00 0
05f6d000-05f6e000 ---p 00000000 00:00 0
05f6e000-0676e000 rw-p 00000000 00:00 0
0676e000-0676f000 ---p 00000000 00:00 0
0676f000-06f6f000 rw-p 00000000 00:00 0
06f6f000-06f70000 ---p 00000000 00:00 0
06f70000-07770000 rw-p 00000000 00:00 0
07770000-07771000 ---p 00000000 00:00 0
07771000-07f71000 rw-p 00000000 00:00 0
38000000-381fc000 r-xp 00200000 08:05 145710 /usr/lib/valgrind/memcheck-amd64-linux
383fb000-383fe000 rw-p 003fb000 08:05 145710 /usr/lib/valgrind/memcheck-amd64-linux
383fe000-3927e000 rw-p 00000000 00:00 0
402001000-403272000 rwxp 00000000 00:00 0
403272000-403274000 ---p 00000000 00:00 0
403274000-403374000 rwxp 00000000 00:00 0
403374000-403376000 ---p 00000000 00:00 0
403376000-40583e000 rwxp 00000000 00:00 0
40583e000-405840000 ---p 00000000 00:00 0
405840000-405940000 rwxp 00000000 00:00 0
405940000-405942000 ---p 00000000 00:00 0
405942000-405946000 rwxp 00000000 00:00 0
405946000-405948000 ---p 00000000 00:00 0
405948000-405a48000 rwxp 00000000 00:00 0
405a48000-405a4a000 ---p 00000000 00:00 0
405a4a000-405a4e000 rwxp 00000000 00:00 0
405a4e000-405a50000 ---p 00000000 00:00 0
405a50000-405b50000 rwxp 00000000 00:00 0
405b50000-405b52000 ---p 00000000 00:00 0
405b52000-405b5a000 rwxp 00000000 00:00 0
405b5a000-405b5c000 ---p 00000000 00:00 0
405b5c000-405c5c000 rwxp 00000000 00:00 0
405c5c000-405c5e000 ---p 00000000 00:00 0
405c5e000-405c62000 rwxp 00000000 00:00 0
7feffd000-7ff001000 rwxp 00000000 00:00 0
7fffb9f36000-7fffb9f57000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
this error is (almost always) caused by appending more elements to an array/vector than said array/vector has been declared as having. therefore i would pay specific attention to all char and uint8 arrays in your code.
though the dump might make sense for someone who understands linux c++ profoundly, it makes no sense for mere mortals and debugging using it is not the fastest solution.
i like the old school approach: print flags to show up to what point your program goes without exceptions. you can usually isolate the offending array(s) this way quite quickly.
as an example, i was having the exact same problem with this code:
std::string GetTimeStringFromDump(unsigned char *bufDumpIn, int startDate) {
unsigned char bufOut[6];
for (int counter02=0;counter02<12;counter02++) {
bufOut[counter02] = bufDumpIn[counter02+startDate];
}
std::string unixTimeOut = GetTimeStringNew(bufOut);
std::cout << "UnixTimeOUT: " << unixTimeOut << std::endl;
return unixTimeOut;
}
the weirdest thing was that the error did NOT occur when i assigned a string that had 12 characters to bufOut (declared as having 6 elements), but rather after
return unixTimeOut;
nevertheless, i changed the declaration to
unsigned char bufOut[12];
and the problem was solved.