I'm trying to delete some instructions in IR. For analysis purpose, these instructions are inserted before, and now I need to delete them.
BasicBlock::reverse_iterator I = (*b).rbegin();
BasicBlock::reverse_iterator Ie = (*b).rend();
int i=0;
for ( ; I != Ie;I++)
{
if(i>0&&i<4){
errs()<<" Instruction "<<*I<<"\n";
I->eraseFromParent();
i++;
}
else{
i++;
}
}
This code is used in Transformation pass. When I run it, the output error are:
#0 0x00000000032bff15 (opt+0x32bff15)
#1 0x00000000032bffa6 (opt+0x32bffa6)
#2 0x00000000032be43e (opt+0x32be43e)
#3 0x00000000032bf8ac (opt+0x32bf8ac)
#4 0x00007f26cfa81330 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
#5 0x00007f26ce81a89a llvm::PointerIntPair<llvm::ilist_node_base<true>*, 1u, unsigned int, llvm::PointerLikeTypeTraits<llvm::ilist_node_base<true>*>, llvm::PointerIntPairInfo<llvm::ilist_node_base<true>*, 1u, llvm::PointerLikeTypeTraits<llvm::ilist_node_base<true>*> > >::getInt() const /home/rasha/llvm/llvm/include/llvm/ADT/PointerIntPair.h:59:0
#6 0x00007f26ce813516 llvm::ilist_node_base<true>::isSentinel() const /home/rasha/llvm/llvm/include/llvm/ADT/ilist_node_base.h:46:0
#7 0x00007f26ce813536 llvm::ilist_node_base<true>::isKnownSentinel() const /home/rasha/llvm/llvm/include/llvm/ADT/ilist_node_base.h:47:0
#8 0x00007f 26ce81e1d9 llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, true, false>::operator*() const /home/rasha/llvm/llvm/include/llvm/ADT/ilist_iterator.h:139:0
#9 0x00007f26ce812d6f (anonymous namespace)::BBRemove::runOnModule(llvm::Module&) /home/rasha/llvm/llvm/lib/Transforms/BBRemove/BBRemove.cpp:79:0
#10 0x0000000002c4a2dc (opt+0x2c4a2dc)
#11 0x0000000002c4aa2c (opt+0x2c4aa2c)
#12 0x0000000002c4ac6d (opt+0x2c4ac6d)
#13 0x0000000001512cd4 (opt+0x1512cd4)
#14 0x00007f26cea6cf45 __libc_start_main /build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0
#15 0x00000000014f7a19 (opt+0x14f7a19)
Stack dump:
This error is issued after the first call of eraseFromParent.
BasicBlock::reverse_iterator I = (*b).rbegin();
BasicBlock::reverse_iterator Ie = (*b).rend();
stack<Instruction *> workList;
int i=0;
for ( ; I != Ie;I++)
{
if(i>0&&i<4){
workList.push_back(I);
i++;
}
else{
i++;
}
}
while(!workList.empty()){
Instruction *I=workList.pop();
I->eraseFromParent();
}
Do not modify instruction within the iterator; collect it first then modify.
Related
I have a recursive function solveCountdownProblem which calls evaluateCountdown which takes an expression in reverse-polish notation format. evaluateCountdown is in a series of nested for loops (in solveCountdownProblem) so is called a lot of times.
double evaluateCountdown(string rpnIn) {
vector<double> stack;
double a = 0, b = 0;
string token = "";
char arithToken;
for (int i = 0; i < rpnIn.size(); ++i) {
if (rpnIn[i] == ' ') {
if (token != "") {
stack.push_back(stod(token)); // Push number to stack
token = "";
}
} else {
if (find(arithOperators.begin(), arithOperators.end(), rpnIn[i]) != arithOperators.end()) { //if char is arithmetic operator
// Pop two numbers of stack and perform operation
// Push result back into stack
arithToken = rpnIn[i];
a = stack.back(); stack.pop_back(); // pops and removes elements
b = stack.back(); stack.pop_back();
if (arithToken == '+') {
stack.push_back(b+a);
} else if (arithToken == '-'){
stack.push_back(b-a);
} else if (arithToken == '/') {
stack.push_back(b/a);
} else if (arithToken == '*') {
stack.push_back(b*a);
}
} else {
token += rpnIn[i]; //add chars to string
}
}
}
return stack.back();
}
It works after some time producing the right calculations but eventually I end up with a memory error 'double free or corruption (out)'. I've used gdb to debug and it produces this backtrace.
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace
#0 __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7bee859 in __GI_abort () at abort.c:79
#2 0x00007ffff7c593ee in __libc_message (action=action#entry=do_abort, fmt=fmt#entry=0x7ffff7d83285 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#3 0x00007ffff7c6147c in malloc_printerr (str=str#entry=0x7ffff7d85670 "double free or corruption (out)") at malloc.c:5347
#4 0x00007ffff7c63120 in _int_free (av=0x7ffff7db4b80 <main_arena>, p=0x5555555733d0, have_lock=<optimized out>) at malloc.c:4314
#5 0x000055555555a932 in __gnu_cxx::new_allocator<double>::deallocate (this=0x7fffffffd270, __p=0x5555555733e0) at /usr/include/c++/9/ext/new_allocator.h:128
#6 0x0000555555559dc0 in std::allocator_traits<std::allocator<double> >::deallocate (__a=..., __p=0x5555555733e0, __n=4) at /usr/include/c++/9/bits/alloc_traits.h:470
#7 0x000055555555932e in std::_Vector_base<double, std::allocator<double> >::_M_deallocate (this=0x7fffffffd270, __p=0x5555555733e0, __n=4) at /usr/include/c++/9/bits/stl_vector.h:351
#8 0x00005555555588fe in std::_Vector_base<double, std::allocator<double> >::~_Vector_base (this=0x7fffffffd270, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/stl_vector.h:332
#9 0x0000555555558953 in std::vector<double, std::allocator<double> >::~vector (this=0x7fffffffd270, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/stl_vector.h:680
#10 0x0000555555556a9a in evaluateCountdown (rpnIn="4 6 5 * + +") at Countdown.h:58
#11 0x0000555555557762 in solveCountdownProblem (operands=std::vector of length 3, capacity 4 = {...}, targetValue=21) at Countdown.h:172
#12 0x0000555555556d61 in solveCountdownProblem (operands=std::vector of length 4, capacity 5 = {...}, targetValue=21) at Countdown.h:113
#13 0x0000555555556d61 in solveCountdownProblem (operands=std::vector of length 5, capacity 6 = {...}, targetValue=21) at Countdown.h:113
#14 0x0000555555556d61 in solveCountdownProblem (operands=std::vector of length 6, capacity 6 = {...}, targetValue=21) at Countdown.h:113
#15 0x0000555555557e17 in main () at TestCountdown.cpp:19
It seems to be pointing to the line 'vector stack;' but I'm not sure why I'm getting a memory error. Doesn't the destructor automatically deallocate 'stack' once it falls out of scope?
If you look into evaluated string "4 6 5 * + +" you can see that there are not enough operands for the last operation + and in your code you do not check if stack has enough elements before calling stack.pop_back() twice. You need to add that check and act accordingly. Probably cleanest way is to wrap popping in a function:
double pop( std::vector<double> &stack )
{
if( stack.empty() ) { // throw exception, return NaN or whatever logic of your program requires
...
}
auto r = stack.back();
stack.pop_back();
return r;
}
then your code is shorter and cleaner:
// Pop two numbers of stack and perform operation
// Push result back into stack
arithToken = rpnIn[i];
double a = pop( stack ); // pops and removes elements
double b = pop( stack );
(and it is better idea to declare and initialize variables when you need them, not in advance)
I have the following function
static node_ptr make_node_ptr()
{
return node_ptr(new node());
}
where using node_ptr = std::shared_ptr<node>;
I tried to find my segmentation fault with valgrind and gdb. In both I get more or less the same stack trace.
Program received signal SIGSEGV, Segmentation fault.
0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
(gdb) bt
#0 0x00007fff8f5d7e82 in szone_malloc_should_clear () from /usr/lib/system/libsystem_malloc.dylib
#1 0x00007fff8f5d7877 in malloc_zone_malloc () from /usr/lib/system/libsystem_malloc.dylib
#2 0x00007fff8f5d6395 in malloc () from /usr/lib/system/libsystem_malloc.dylib
#3 0x00000001000f17d8 in operator new(unsigned long) () from /usr/local/lib/gcc/4.9/libstdc++.6.dylib
#4 0x0000000100009c04 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<msc::scene_manager<float, int, 3ul>::node*> (this=0x7fff5f4002e8, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:569
#5 0x0000000100008c78 in std::__shared_ptr<msc::scene_manager<float, int, 3ul>::node, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr_base.h:871
#6 0x00000001000079e5 in std::shared_ptr<msc::scene_manager<float, int, 3ul>::node>::shared_ptr<msc::scene_manager<float, int, 3ul>::node> (this=0x7fff5f4002e0, __p=0x10059ffc0)
at /usr/local/Cellar/gcc49/4.9.2_1/include/c++/4.9.2/bits/shared_ptr.h:113
#7 0x0000000100005bdc in msc::scene_manager<float, int, 3ul>::make_node_ptr () at ../../common/msc/scene.d/scene_manager_def.h:98
#8 0x00000001000037dd in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (wrappee=...) at ../../common/msc/scene.d/node_impl.h:73
#9 0x0000000100003d53 in msc::scene_manager<float, int, 3ul>::node::generate_wrapping_node (nodes=...) at ../../common/msc/scene.d/node_impl.h:112
#10 0x0000000100004011 in msc::scene_manager<float, int, 3ul>::insert (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:97
#11 0x0000000100006071 in msc::scene_manager<float, int, 3ul>::insert_if_leq (this=0x7fff5f82ee90, root=..., other=...) at ../../common/msc/scene.d/scene_manager_impl.h:127
The last 2 lines repeat endlessly, I guess at least, as I tried to continue until frame #6000 or smth.
Am I missing something or is the creation of this shared_ptr not allowed?
Edit
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
{
bool swapped = false;
if (root == nullptr)
root = other;
else
{
auto inside = msc::inside::test(*root, *other);
if (inside == msc::inside::NONE)
{
auto oldRoot = root;
root = node::generate_wrapping_node(
std::vector<node_c_ptr>{ oldRoot, other });
insert_if_leq(root, oldRoot);
}
else if ((swapped = (inside == msc::inside::FIRST)))
{
std::swap(root, other);
}
other = insert_if_leq(root, other);
}
return !swapped ? other : root;
}
node_ptr scene_manager::insert_if_leq(node_ptr root, node_ptr other)
{
node_ptr res = root;
if (are_similar(*root, *other))
msc::move_append(root->children, other->children);
else
{
auto idx = root->get_quadrant_idx(other->center);
res = insert(root->quadrants[idx], other);
}
return res;
}
These are the functions which repeat. msc is my own namespace.
As the functions are recursive insert calls insert_if_leq and vice versa, I had to make node_ptr root in insert_if_leq a reference, because the assignment in insert depended on it. The new function definitions are as follows:
node_ptr scene_manager::insert(node_ptr & root, node_ptr other)
node_ptr scene_manager::insert_if_leq(node_ptr & root, node_ptr other)
any help ? using confbridge,conf as confbridge is way making conference same as meetme.conf
**=====================================================================
Asterisk-11.5.1 Centos6 app_confbridge.c
=====================================================================
APP: MyConfbridgeCount(Confbridgename,variablename)
it will return no of user in conference if conference is created or else zero.
Task: Using Dailplan user want to retrive no of user in conference
'6050' =>
1. Verbose(3,"testMyConfbridgeCount") [pbx_config]
2. MyConfbridgeCount(4000,count) [pbx_config]
3. verbose(3,"== ${count} ====") [pbx_config]
======================================================================
issue:Currently asterisk core dumped as soon as app2 load .
I want to load module as after join confbridge by any user , using MyConfbridgeCount() to know no of conference user count .
file: app/app_confbrige.c**
==========================================================================
partial code of app_confbridge.c:
=========================================================================
static const char *const app2 ="MyConfbridgeCount";
static int count_exec(struct ast_channel *chan, const char *data)
{
int res = 0;
struct conference_bridge *conf=NULL;
int count;
char *localdata;
char val[80] = "0";
struct ao2_iterator i;
//struct conference_bridge *bridge = NULL;
struct conference_bridge tmp;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(confno);
AST_APP_ARG(varname);
);
ast_verb(3,"\n============Inside count_exec =============\n");
if ( ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "MyConfbrigeCount requires an argument (conference number)\n");
ast_verb(3, "\n MyConfbrigeCount requires an argument (conference number\n ");
return -1;
}
if (!ao2_container_count(conference_bridges)) {
ast_verb(3, "No active conferences.");
ast_log(LOG_NOTICE, "No active conferences.");
return -1;
}
if (!(localdata = ast_strdupa(data))){
return -1;
}
AST_STANDARD_APP_ARGS(args, localdata);
ast_copy_string(tmp.name, args.confno, sizeof(tmp.name));
conf = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
if (conf) {
ao2_lock(conf);
count = conf->markedusers;
ao2_unlock(conf);
}else{
count = 0;
}
if (!ast_strlen_zero(args.varname)) {
snprintf(val, sizeof(val), "%d", count);
pbx_builtin_setvar_helper(chan, args.varname, val);
} else {
if ( ast_channel_state(chan)!= AST_STATE_UP) {
ast_answer(chan);
}
res = ast_say_number(chan, count, "",ast_channel_language(chan),(char *) NULL);
}
return res;
}
static int load_module(void)
{
ast_verb(3 ,"==Inside load_module==");
res |= ast_register_application_xml(app2,count_exec);
return res;
}
static int unload_module(void)
{
res |= ast_unregister_application(app2);
return res;
}
static struct ast_cli_entry cli_confbridge[] = {
AST_CLI_DEFINE(count_exec, "MyConfbrigdeCount Show Number of adminUser(s) in Conference." ),
}
============core dump=================================================
Program terminated with signal 11, Segmentation fault.
#0 __strlen_ia32 () at ../sysdeps/i386/i586/strlen.S:56
56 cmpb %dh, (%eax) /* is byte NUL? *
(gdb) bt
#0 __strlen_ia32 () at ../sysdeps/i386/i586/strlen.S:56
#1 0x00c1b4df in _IO_vfprintf_internal (s=0xfffffffe, format=<value optimized out>, ap=<value optimized out>) at vfprintf.c:1641
#2 0x00c409f0 in _IO_vsnprintf (string=0x835af1c "\374 -- \n======== inside count_exec == data is at address:[0xbf918b64] data:[nnel)\n", maxlen=<value optimized out>,
format=0xbf9175c0 "\374 -- \n======== inside count_exec == data is at address:[%p] data:[%s] ", '=' <repeats 11 times>, "\n",
args=0xbf917724 "d\213\221\277\376\377\377\377\213\261\065\b") at vsnprintf.c:120
#3 0x081a0f94 in __ast_str_helper (buf=0xbf9176a8, max_len=0, append=0,
fmt=0xbf9175c0 "\374 -- \n======== inside count_exec == data is at address:[%p] data:[%s] ", '=' <repeats 11 times>, "\n",
ap=0xbf917724 "d\213\221\277\376\377\377\377\213\261\065\b") at strings.c:76
#4 0x081b17d0 in ast_str_set_va (buf=0xbf9176a8, max_len=0,
fmt=0xbf9175c0 "\374 -- \n======== inside count_exec == data is at address:[%p] data:[%s] ", '=' <repeats 11 times>, "\n",
ap=0xbf917724 "d\213\221\277\376\377\377\377\213\261\065\b") at /usr/src/My-asterisk/asterisk-11.5.1/include/asterisk/strings.h:803
#5 0x08134a6f in __ast_verbose_ap (file=0xe1ca74 "app_confbridge.c", line=2453, func=0xe20652 "count_exec", level=3, callid=0x0,
fmt=0xbf9175c0 "\374 -- \n======== inside count_exec == data is at address:[%p] data:[%s] ", '=' <repeats 11 times>, "\n",
ap=0xbf917724 "d\213\221\277\376\377\377\377\213\261\065\b") at logger.c:1818
#6 0x08134b0b in __ast_verbose (file=0xe1ca74 "app_confbridge.c", line=2453, func=0xe20652 "count_exec", level=3,
fmt=0xe1da30 "\n======== inside count_exec == data is at address:[%p] data:[%s] ", '=' <repeats 11 times>, "\n") at logger.c:1836
#7 0x00e09a45 in count_exec (chan=0xe23c18, data=0xfffffffe <Address 0xfffffffe out of bounds>) at app_confbridge.c:2453
#8 0x080d40eb in __ast_cli_register (e=0xe23c18, ed=0x0) at cli.c:2118
#9 0x080d4459 in ast_cli_register (e=0xe23c18) at cli.c:2178
#10 0x080d4482 in ast_cli_register_multiple (e=0xe237a0, len=13) at cli.c:2189
#11 0x00e11f7d in load_module () at app_confbridge.c:4771
#12 0x0812ba89 in start_resource (mod=0x87fa908) at loader.c:845
#13 0x0812c45c in load_resource_list (load_order=0xbf918e90, global_symbols=0, mod_count=0xbf918e88) at loader.c:1045
#14 0x0812ca5a in load_modules (preload_only=0) at loader.c:1198
#15 0x080895f7 in main (argc=4, argv=0xbf91a3a4) at asterisk.c:4180
As i underestand you created NEW application MyConfbridgeCount,right?
And you are not voip nor c++ expert.
If so, recommended way is use GROUP functions to calculate number of channels BEFORE confbridge. That can be done via pure dialplan.
Creating c/c++ app require very carefull coding and multithreaded debugging(which is extreamly complex thing).
If you realy care what is your error - your error is sending to printf function incorrect address of string.
I'm working on my first C++ extension for a python program. I have been trying to debug this particular piece of code for hours and I am out of ideas.
The segfault seems to have something to do with the PyArrayObject old_simplices_array that is getting passed to the C++ code. That object is a 2d numpy array of type uint32.
This code was modified directly from what scipy.weave puts together. Everything works fine when the code is formatted for and used by scipy.weave.inline. This seems to eliminate the python portion of my program and the algorithm itself from being possible culprits.
That just leaves the syntax and types. Does anyone see any incorrect syntax or type casting the code?
static PyObject* exterior(PyObject* self,
PyArrayObject* old_simplices_array)
{
const short unsigned int step = old_simplices_array->dimensions[1];
const short unsigned int j_max = step - 1;
const long unsigned int col_max =
old_simplices_array->dimensions[0] * step;
short unsigned int j, k, face_index;
long unsigned int col;
unsigned int num_simplices = 0;
PyObject* indices = PyList_New(0);
PyObject* indptr = PyList_New(0);
PyObject* data = PyList_New(0);
PyObject* simplices = PyList_New(0);
PyList_Append(indptr, PyLong_FromLong(0));
PyObject* simplex_to_index = PyDict_New();
for(col = 0; col < col_max; col+=step)
{
for(j = 0; j <= j_max; j++)
{
face_index = 0;
PyObject* face = PyTuple_New(j_max);
for(k = 0; k <= j_max; k++)
{
if(j != k)
{
PyTuple_SetItem(face, face_index,
PyLong_FromLong(old_simplices_array->data[col + k]));
face_index++;
}
}
if(PyDict_Contains(simplex_to_index, face))
{
PyList_Append(indices,
PyDict_GetItem(simplex_to_index, face));
}
else
{
PyDict_SetItem(simplex_to_index, face,
PyLong_FromLong(num_simplices));
PyList_Append(simplices, face);
num_simplices++;
}
PyList_Append(data, PyLong_FromLong(1 - 2 * (j % 2)));
}
PyList_Append(indptr, PyLong_FromLong(col + j));
}
return PyTuple_Pack(3, PyTuple_Pack(3, data, indices, indptr), simplices,
simplex_to_index);
}
------UPDATE------
gdb indicates
const short unsigned int step = old_simplices_array->dimensions[1];
causes a segfault. Did I misuse types?
------UPDATE------
Despite GDB telling me,
const short unsigned int step = old_simplices_array->dimensions[1];
causes the segfault, if I return from the program just before the for loop, I get no segfault (just an error on the python side complaining about returning a NoneType).
This is the full backtrace:
Program received signal SIGSEGV, Segmentation fault.
exterior (self=<optimized out>, old_simplices_array=0xec0a50)
at src/_alto.cpp:39
warning: Source file is more recent than executable.
39 const short unsigned int step = old_simplices_array->dimensions[1];
(gdb) bt
exterior (self=<optimized out>, old_simplices_array=0xec0a50)
at src/_alto.cpp:39
0x00007ffff7aedad2 in PyEval_EvalFrameEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeddc9 in PyEval_EvalFrameEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902 in PyEval_EvalCodeEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a70ad6 in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a53b80 in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aaaea0 in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aa68bc in ?? ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7a4565e in PyObject_Call ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7ae9bce in PyEval_EvalFrameEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aee902 in PyEval_EvalCodeEx ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7aeea32 in PyEval_EvalCode ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b103fa in PyRun_FileExFlags ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b10e3d in PyRun_SimpleFileExFlags ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff7b26972 in Py_Main ()
from /usr/lib/sagemath/local/lib/libpython2.7.so.1.0
0x00007ffff6d29ea5 in __libc_start_main ()
from /lib/x86_64-linux-gnu/libc.so.6
0x00000000004006d1 in _start ()
In general, the signature of a method in a C module is PyObject* f(PyObject* self, PyObject* args), where args is intended to be parsed by PyArg_ParseTuple. You can see this in the code scipy.weave generates: http://docs.scipy.org/doc/scipy/reference/tutorial/weave.html#a-quick-look-at-the-code). Unless there's some wrapper function you haven't posted that calls PyArg_ParseTuple for you, your exterior method must call it to extract the PyArrayObject from the generic PyObject* args.
I have the following std::map defined:
//The map holding the list of registered services per partition key.
std::map<SRServicePartitionKey, std::vector<EndPointAddr*>* > mServiceMap;
I have below indicated function whose aim is to remove a specific EndPointAddr* pointer in the vector that is kept in the value of the above defined Map instance. I am getting a SEGABORT in gdb after the following scenario realized:
Add multiple items to the map
Delete the items using the below function one by one.
Add those deleted items again (a few of them)
Delete one item ==> AT THIS POINT I get a sigabort in GDB with the following message:
* glibc detected * /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/build_output/ServiceRegistrar: double free or corruption (fasttop): 0x00007ffff0002e10 *
GDB Back trace is available at the bottom...
QUESTION
What particular things do you think are wrong in this removal function below? Why do I get this "Double free or corruption" error? What do you think I am missing in the removal function where I first find the item to be deleted, then remove it from the vector and finally deallocate it.
REMOVAL FUNCTION
bool
ServiceRegistrar::removeService(const EndPointAddr & epAddrForRemoval)
{
bool condErased = false;
for(auto it = mServiceMap.begin(); it != mServiceMap.end(); ++it)
{
std::cout << "\tPartition ["
<< (*it).first.getInstanceNo() << ","
<< (*it).first.getContext() << ","
<< (*it).first.getVersion() << "]:"
<< std::endl;
std::vector<EndPointAddr*> * serviceList = (*it).second;
auto found =
std::find_if(serviceList->begin(),
serviceList->end(),
[epAddrForRemoval]( EndPointAddr* otherEPAddr )
{
const EndPointTipcAddr & tipcAddrToRemove = epAddrForRemoval.getImmutableTipcAddress();
const EndPointTipcAddr & otherTipcAddr = otherEPAddr->getImmutableTipcAddress();
return (tipcAddrToRemove.compareTo(otherTipcAddr));
});
EndPointAddr * toBeDeAllocatedEP = *found;
auto toBeErasedEP =
std::remove_if(serviceList->begin(),
serviceList->end(),
[epAddrForRemoval]( EndPointAddr* otherEPAddr )
{
const EndPointTipcAddr & tipcAddrToRemove = epAddrForRemoval.getImmutableTipcAddress();
const EndPointTipcAddr & otherTipcAddr = otherEPAddr->getImmutableTipcAddress();
return (tipcAddrToRemove.compareTo(otherTipcAddr));
});
if(toBeErasedEP != serviceList->end())
{
serviceList->erase(toBeErasedEP, serviceList->end());
condErased = true;
}
if(toBeDeAllocatedEP != 0)
{
!!!!!!!!!!!!LINE 1396 is HERE!!!!!!!!!!!!!!!
delete toBeDeAllocatedEP;
}
} //end of For Loop
return condErased;
}
GDB BackTrace
(gdb) bt
#0 0x00007ffff7026425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7029b8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff706439e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff706eb96 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007ffff7681540 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x0000000000434604 in EndPointIpAddr::~EndPointIpAddr (this=0x7ffff0002fb0, __in_chrg=<optimized out>) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_components/../control_api/api_util/EndPointIpAddr.hpp:28
#6 0x0000000000434660 in EndPointAddr::~EndPointAddr (this=0x7ffff0002f90, __in_chrg=<optimized out>) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_components/../control_api/api_util/EndPointAddr.hpp:36
#7 0x000000000043c97f in ServiceRegistrar::removeService (this=0x7fffffffdea0, epAddrForRemoval=...) at /home/holb/DESIGN/ECLB_CP/REPs/V2/eclb_cp/src/control_api/ServiceRegistrar.cpp:1396
You appear to be using found without checking if it's valid or not. If you were to fail to find a value and find_if returned serviceList->end(), you'd be dereferencing serviceList->end().
The variable you're storing this dereferenced value to is the one that's causing you trouble later when you attempt to delete it. Are you sure you're actually finding a matching value?