Closed kornefalk closed 9 years ago
Hi,
I've found the root cause and committed a fix for it :) Let me know if the issue is solved on your side with latest code (C and C++ code) in order to close the issue.
Thanks
Regards,
Vincent
Corrections verified successfully.
Now I get the Oracle desired error (ORA-29970: Specified registration id does not exist).
good :)
Running example code from "Database notifications" will cause crash if Register fails
Tested both running on Red Hat Enterprise Linux Server release 6.5 (Santiago) and Oracle Solaris 10 8/11 s10s_u10wos_17b SPARC using GCC 4.9.2 compiler.
Running sample code ``` c++ Step 1 Step 2 Step 3 Step 4 Step 5 Step 6 Step 7 Step 8 *** glibc detected *** ./eventTest: double free or corruption (!prev): 0x000000000191d030 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3edb475e66] /lib64/libc.so.6[0x3edb4789b3] /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so.4(OCI_StatementFree+0x4e)[0x7f087aab85ae] ./eventTest[0x409641] ./eventTest[0x409868] ./eventTest[0x40c1ce] /lib64/libc.so.6(__libc_start_main+0xfd)[0x3edb41ed5d] ./eventTest[0x404211] ```
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options
Running with gdb ``` c++ Program received signal SIGABRT, Aborted. 0x0000003edb432625 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); (gdb) bt #0 0x0000003edb432625 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #1 0x0000003edb433e05 in abort () at abort.c:92 #2 0x0000003edb470537 in __libc_message (do_abort=2, fmt=0x3edb558820 " glibc detected %s: %s: 0x%s **\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:198 #3 0x0000003edb475e66 in malloc_printerr (action=3, str=0x3edb558bb0 "double free or corruption (!prev)", ptr=) at malloc.c:6336
#4 0x0000003edb4789b3 in _int_free (av=0x3edb78fe80, p=0x6fd030, have_lock=0) at malloc.c:4832
#5 0x00007ffff7dd85ae in OCI_StatementFree () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so.4
#6 0x0000000000409641 in ocilib::HandleHolder::SmartHandle::~SmartHandle() ()
at /home/kornefab/ocilib/linux/include/ocilib_impl.hpp:702
#7 0x0000000000409868 in ocilib::HandleHolder::SmartHandle::Release(ocilib::HandleHolder) ()
at /home/kornefab/ocilib/linux/include/ocilib_impl.hpp:710
#8 0x000000000040c1ce in main () at eventTest.cpp:38
```
source code ``` c++ #include
#include "ocilib.hpp"
#include
using namespace ocilib;
using namespace std;
#ifdef _WINDOWS
#define sleep(x) Sleep(x*1000)
#endif
#define WaitForEvents() sleep(5)
#define WaitForDatabase() sleep(60)
static std::map EventTypes;
static std::map ObjectEvents;
void EventHandler(Event &evt);
void SetupNames();
int main(int argc, char* argv[])
{
if (argc != 4) // Check number of arguments
{
cout << "eventTest user pwd connection" << endl;
return -1;
}
string user(argv[1]);
string pwd(argv[2]);
string connect(argv[3]);
int count=0;
SetupNames();
cerr << "Step " << (++count) << endl;
try
{
Environment::Initialize(Environment::Events);
cerr << "Step " << (++count) << endl;
//Connection con("db", "usr", "pwd");
Connection con(connect, user, pwd);
cerr << "Step " << (++count) << endl;
con.SetAutoCommit(true);
cerr << "Step " << (++count) << endl;
Statement st(con);
cerr << "Step " << (++count) << endl;
st.Execute("create table table1(code number)");
cerr << "Step " << (++count) << endl;
st.Execute("create table table2(str varchar2(10))");
cerr << "Step " << (++count) << endl;
Subscription sub;
cerr << "Step " << (++count) << endl;
sub.Register(con, "sub-00", Subscription::AllChanges, EventHandler, 5468, 0);
cerr << "Step " << (++count) << endl;
sub.Watch("select * from table1");
cerr << "Step " << (++count) << endl;
sub.Watch("select * from table2");
cerr << "Step " << (++count) << endl;
st.Execute("alter table table1 add price number");
cerr << "Step " << (++count) << endl;
WaitForEvents();
cerr << "Step " << (++count) << endl;
st.Execute("insert into table1 values(1, 10.5)");
cerr << "Step " << (++count) << endl;
st.Execute("insert into table2 values('shoes')");
cerr << "Step " << (++count) << endl;
WaitForEvents();
cerr << "Step " << (++count) << endl;
st.Execute("update table1 set price = 13.5 where code = 1");
cerr << "Step " << (++count) << endl;
st.Execute("delete from table2 ");
cerr << "Step " << (++count) << endl;
WaitForEvents();
cerr << "Step " << (++count) << endl;
st.Execute("drop table table1");
cerr << "Step " << (++count) << endl;
st.Execute("drop table table2");
cerr << "Step " << (++count) << endl;
WaitForEvents();
cerr << "Step " << (++count) << endl;
con.Close();
cerr << "Step " << (++count) << endl;
/* start remote instance */
cerr << "Step " << (++count) << endl;
Environment::StartDatabase("db", "sys_usr", "sys_pwd", Environment::StartForce, Environment::StartFull);
cerr << "Step " << (++count) << endl;
/* shutdown remote instance */
Environment::ShutdownDatabase("db", "sys_usr", "sys_pwd", Environment::ShutdownAbort, Environment::ShutdownFull);
cerr << "Step " << (++count) << endl;
WaitForDatabase();
cerr << "Step " << (++count) << endl;
sub.Unregister();
cerr << "Step " << (++count) << endl;
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
Environment::Cleanup();
}
void SetupNames()
{
EventTypes[Event::DatabaseStart] = "Startup";
EventTypes[Event::DatabaseShutdown] = "Shutdown";
EventTypes[Event::DatabaseShutdownAny] = "Shutdown Any";
EventTypes[Event::DatabaseDrop] = "Drop Database";
EventTypes[Event::Unregister] = "Unregister";
EventTypes[Event::ObjectChanged] = "Object Changed";
ObjectEvents[Event::ObjectInserted] = "Insert";
ObjectEvents[Event::ObjectUpdated] = "Update";
ObjectEvents[Event::ObjectDeleted] = "Delete";
ObjectEvents[Event::ObjectAltered] = "Alter";
ObjectEvents[Event::ObjectDropped] = "Drop";
ObjectEvents[Event::ObjectGeneric] = "Generic";
}
void EventHandler(Event &evt)
{
static int count=0;
cerr << "EventHandler " << (++count) << endl;
std::cout << "** Notification : " << evt.GetSubscription().GetName() << std::endl;
std::cout << "** Database : " << evt.GetDatabaseName() << std::endl;
std::cout << "** Event : " << EventTypes[evt.GetType()] << std::endl;
if (evt.GetType() == Event::ObjectChanged)
{
std::cout << ".... Object : " << evt.GetObjectName() << std::endl;
std::cout << ".... Action : " << ObjectEvents[evt.GetObjectEvent()] << std::endl;
std::cout << ".... RowID : " << evt.GetRowID() << std::endl;
}
std::cout << std::endl;
}
```