{"action":"created","issue":{"url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/issues/58","labels_url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/issues/58/labels{/name}","comments_url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/issues/58/comments","events_url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/issues/58/events","html_url":"https://github.com/NeuronRobotics/nrjavaserial/pull/58","id":124092530,"number":58,"title":"Solve problem with eis C struct going out of scope after Java method exits","user":{"login":"cxbrooks","id":861991,"avatar_url":"https://avatars.githubusercontent.com/u/861991?v=3","gravatar_id":"","url":"https://api.github.com/users/cxbrooks","html_url":"https://github.com/cxbrooks","followers_url":"https://api.github.com/users/cxbrooks/followers","following_url":"https://api.github.com/users/cxbrooks/following{/other_user}","gists_url":"https://api.github.com/users/cxbrooks/gists{/gist_id}","starred_url":"https://api.github.com/users/cxbrooks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cxbrooks/subscriptions","organizations_url":"https://api.github.com/users/cxbrooks/orgs","repos_url":"https://api.github.com/users/cxbrooks/repos","events_url":"https://api.github.com/users/cxbrooks/events{/privacy}","received_events_url":"https://api.github.com/users/cxbrooks/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-12-28T17:08:57Z","updated_at":"2015-12-28T20:00:00Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/pulls/58","html_url":"https://github.com/NeuronRobotics/nrjavaserial/pull/58","diff_url":"https://github.com/NeuronRobotics/nrjavaserial/pull/58.diff","patch_url":"https://github.com/NeuronRobotics/nrjavaserial/pull/58.patch"},"body":"I'm resubmitting this pull request from a branch that does not include a bunch of intermediate commits.\r\n\r\n\r\n\r\nUnder Mac OS X, running a Ptolemy model (SerialHelloWorld.xml )model was crashing Java in readArray().\r\n\r\nThe model opens two ports, writes to one port and halts after 5 seconds.\r\n\r\nThe code does not use the RXTXListener facility, instead it creates reader and writer threads.\r\n\r\nThe cause is that when the Java RXTXPort.run() method exits, a C struct named eis goes out of scope. If the drain thread tries to access eis after a timeout, then a segfault occurs.\r\n\r\nWhat's happening is that in nrjavaserial/src/main/c/src/SerialImp.c, readArray() is calling read_byte_array() and read_byte_array() is crashing when eis is accessed:\r\n```c\r\n        while( bytes < length &&  count++ < 20 ) /* && !is_interrupted( eis ) )*/\r\n        {\r\n                if (timeout >= 0) {\r\n                        now = GetTickCount();\r\n                        if ( now-start >= timeout )\r\n                        {\r\n--->                            eis->eventflags[SPE_DATA_AVAILABLE] = flag;\r\n                                return bytes;\r\n                        }\r\n                }\r\n```\r\n\r\nThe reason that it is crashing here is because eis is allocated in eventLoop() in SerialImp.c by struct event_info_struct eis:\r\n\r\n```c\r\nJNIEXPORT void JNICALL RXTXPort(eventLoop)( JNIEnv *env, jobject jobj )\r\n{\r\n#ifdef WIN32\r\n        int i = 0;\r\n#endif /* WIN32 */\r\n        struct event_info_struct eis;\r\n        eis.jclazz = (*env)->GetObjectClass( env, jobj );\r\n        eis.env = env;\r\n        eis.jobj = &jobj;\r\n        eis.initialised = 0;\r\n\r\n        ENTER( \"eventLoop\\n\" );\r\n        if ( !initialise_event_info_struct( &eis ) ) goto end;\r\n        if ( !init_threads( &eis ) ) goto end;\r\n```\r\n\r\ninit_threads() sets the Java eis object:\r\n\r\n```c\r\n        report(\"init_threads: get eis\\n\");\r\n        jeis  = (*eis->env)->GetFieldID( eis->env, eis->jclazz, \"eis\", \"J\" );\r\n        report(\"init_threads: set eis\\n\");\r\n        (*eis->env)->SetLongField(eis->env, *eis->jobj, jeis, ( size_t ) eis );\r\n```\r\n\r\nnrjavaserial/src/main/java/gnu/io/RXTXPort.java invokes eventLoop()\r\n\r\n\r\n```c\r\n        /** a pointer to the event info structure used to share information \r\n            between threads so write threads can send output buffer empty   \r\n            from a pthread if need be.     \r\n\r\n            long for 64 bit pointers.                                                                                                    \r\n        */\r\n        long eis = 0;\r\n\r\n...\r\n\r\n        /** Process SerialPortEvents */\r\n        native void eventLoop();\r\n\r\n...\r\n\r\n\r\n        /**                                                                                                                              \r\n        *  run the thread and call the event loop.                                                                                      \r\n        */\r\n                public void run()\r\n                {\r\n                        if (debug)\r\n                                z.reportln( \"RXTXPort:MontitorThread:run()\");\r\n                        monThreadisInterrupted=false;\r\n                        eventLoop();\r\n                        if (debug)\r\n                                z.reportln( \"eventLoop() returned\");\r\n                }\r\n```\r\n\r\nSo, if the run() method ends, the eis automatic variable in eventloop() goes out of scope.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/issues/comments/167642951","html_url":"https://github.com/NeuronRobotics/nrjavaserial/pull/58#issuecomment-167642951","issue_url":"https://api.github.com/repos/NeuronRobotics/nrjavaserial/issues/58","id":167642951,"user":{"login":"madhephaestus","id":1254726,"avatar_url":"https://avatars.githubusercontent.com/u/1254726?v=3","gravatar_id":"","url":"https://api.github.com/users/madhephaestus","html_url":"https://github.com/madhephaestus","followers_url":"https://api.github.com/users/madhephaestus/followers","following_url":"https://api.github.com/users/madhephaestus/following{/other_user}","gists_url":"https://api.github.com/users/madhephaestus/gists{/gist_id}","starred_url":"https://api.github.com/users/madhephaestus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/madhephaestus/subscriptions","organizations_url":"https://api.github.com/users/madhephaestus/orgs","repos_url":"https://api.github.com/users/madhephaestus/repos","events_url":"https://api.github.com/users/madhephaestus/events{/privacy}","received_events_url":"https://api.github.com/users/madhephaestus/received_events","type":"User","site_admin":false},"created_at":"2015-12-28T20:00:00Z","updated_at":"2015-12-28T20:00:00Z","body":"Is this resolving an open issue, and if so can you make reference to it in a comment. Otherwise, can you make an issue, and add a commit or comment that closes the issue you just created. "}}