Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscription.Register crashes if subscribtion files #3

Closed
kornefalk opened this issue Jul 14, 2015 · 3 comments
Closed

Subscription.Register crashes if subscribtion files #3

kornefalk opened this issue Jul 14, 2015 · 3 comments
Assignees

Comments

@kornefalk
Copy link

Running example code from "Database notifications" will cause crash if Register fails

  Subscription sub;
  sub.Register(con, "sub-00", Subscription::AllChanges, EventHandler, 5468, 0);

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
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
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=<value optimized="" out="">) 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<OCI_Statement*>::SmartHandle::~SmartHandle() ()
at /home/kornefab/ocilib/linux/include/ocilib_impl.hpp:702
#7 0x0000000000409868 in ocilib::HandleHolder<OCI_Statement*>::SmartHandle::Release(ocilib::HandleHolder<OCI_Statement*>) ()
at /home/kornefab/ocilib/linux/include/ocilib_impl.hpp:710
#8 0x000000000040c1ce in main () at eventTest.cpp:38

source code
#include <iostream>
#include "ocilib.hpp"
#include <unistd.h>

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<unsigned int, ostring> EventTypes;
static std::map<unsigned int, ostring> 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;
}

@vrogier
Copy link
Owner

vrogier commented Jul 14, 2015

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

@kornefalk
Copy link
Author

Corrections verified successfully.

Now I get the Oracle desired error (ORA-29970: Specified registration id does not exist).

@vrogier
Copy link
Owner

vrogier commented Jul 14, 2015

good :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants