LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-27-2012, 05:58 AM   #1
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Rep: Reputation: Disabled
Crashes in throwing exceptions if code compiled in 32 bit explicity on 64 bit system


Hi LQ Memebers,

We have one shared libary which is used by Java Program using JNI. In this native libary, we throw standard exception using JNI methods,which by the way work fine.

Due to some constraint, we are forced to compile this library in both modes ( 32 & 64 bit) only on 64 bit server using -m32 options.

Now, the 32 bit compiled version is run on 32 bit systems and the libary crashes while attempting to throw an exception to Java program. However, if the libary is compiled on 32 bit system, it works just fine.

This is my error class,

#include <exception>
#include <sstream>

//! Base error class
class Error : public std::exception {
public:
/*! The explicit use of this constructor is not advised. Use the GO_FAIL macro instead */
Error(const std::string& message = "") : message_(message) {};

/*! the automatically generated destructor would not have the throw specifier */
virtual ~Error() throw() {}

//! returns the error message.
const char* what() const throw () { return message_.c_str(); }

private:
std::string message_;
};

Usage :
throw Error("Any error");

the program fails with the following msg.

terminate called after throwing an instance of 'Error'
what(): Any error


But if i compiled my library on 32 bit system itself, it just throws an error msg..

Any error

Why is this happening ? I have also tried taking the code in debug (gdb), but the control never reaches catch block.

Any help would be highly appreciated..

Thanks,
Gaurav
 
Old 01-27-2012, 08:47 AM   #2
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Original Poster
Rep: Reputation: Disabled
Any body.. pls put forth your comments..
 
Old 01-27-2012, 12:01 PM   #3
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by gaurav.rustagi View Post
Any body.. pls put forth your comments..
Presumably, when a ball is thrown, there's someone else to catch it. It's the same concept when dealing with exceptions... if one is thrown, then somewhere in the code, it should be caught.

Try augmenting your code to have the following construct:
Code:
...

try
{
   throw Error("Any error");
}
catch (std::exception& e)
{
   std::cout << e.what() << std::endl;
}

...
 
Old 01-27-2012, 02:04 PM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,851
Blog Entries: 1

Rep: Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868
Are you sure that it is okay to use C++ from JNI?
 
Old 01-27-2012, 02:21 PM   #5
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by dwhitney67 View Post
Presumably, when a ball is thrown, there's someone else to catch it. It's the same concept when dealing with exceptions... if one is thrown, then somewhere in the code, it should be caught.

Try augmenting your code to have the following construct:
Code:
...

try
{
   throw Error("Any error");
}
catch (std::exception& e)
{
   std::cout << e.what() << std::endl;
}

...
yes sire, this is very obvious code fragments which i had not put in my post. It does not even come to catch() block. It just fails during throw Error("Any error"). However, it works fine if the shared library had been compiled on 32 bit server. This is an issue regarding Cross compilation. It has something to do with this Error class.

Anyways, Thanks for your reply.
 
Old 01-27-2012, 02:24 PM   #6
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
Are you sure that it is okay to use C++ from JNI?

Yes, That is the use of JNI, to call native libraries. In this case, the native library is written in C++.
 
Old 01-27-2012, 03:47 PM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,851
Blog Entries: 1

Rep: Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868Reputation: 1868
Thanks (back in my times JNI meant C, not C++).
 
1 members found this post helpful.
Old 01-27-2012, 03:55 PM   #8
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
Thanks (back in my times JNI meant C, not C++).
I mean the native functions are C type only, but inside that code you can use class features.

Last edited by gaurav.rustagi; 01-27-2012 at 03:56 PM. Reason: spell error
 
Old 01-28-2012, 07:51 AM   #9
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by gaurav.rustagi View Post
... It does not even come to catch() block. It just fails during throw Error("Any error"). However, it works fine if the shared library had been compiled on 32 bit server. This is an issue regarding Cross compilation. It has something to do with this Error class.
Through some experimentation, I was able to get the following code to work, under separate environments (32-bit and 64-bit), however I was unable to use the -m32 option on my 64-bit system; presumably this system is missing some critical development files.

Native.java:
Code:
import java.util.*;

class Native
{
   native public void function();

   static {
      System.loadLibrary("Native");
   }

   public static void main(String[] args)
   {
      try {
         Native nat = new Native();
         nat.function();
      }
      catch (Throwable e) {
         System.out.println("Java exception handled; cause: " + e);
      }
   }
}
Native.cpp:
Code:
#include <jni.h>
#include <stdexcept>
#include <string>
#include <iostream>

#include "Native.h"


class Error : public std::exception
{
public:
   Error(const std::string& message) : msg(message) {}

   virtual ~Error() throw() {}

   const char* what() const throw() { return msg.c_str(); }

private:
   std::string msg;
};


JNIEXPORT void JNICALL Java_Native_function(JNIEnv* env, jobject jobj)
{
   try
   {
      throw Error("Any error");
   }
   catch (std::exception& e)
   {
      std::cout << "C++ exception handled; cause: " << e.what() << std::endl;

      jclass exceptionClass = env->FindClass("java/lang/IllegalArgumentException");

      if (exceptionClass)
      {
         env->ThrowNew(exceptionClass, e.what());
      }
   }
}
I used the following Makefile to build and run the code:
Code:
JAVA_SRCS = Native.java
JAVA_CLAS = $(JAVA_SRCS:.java=)

CXX_SRCS  = Native.cpp
CXX_OBJS  = $(CXX_SRCS:.cpp=.o)

JNI_LIB   = libNative.so

JAVAC     = /usr/bin/javac
JAVAH     = /usr/bin/javah
JAVA      = /usr/bin/java

JVM_HOME  = /usr/lib/jvm/java-6-sun-1.6.0.26

ARCH      =
INCLUDES  = -I/usr/lib/jni -I$(JVM_HOME) -I$(JVM_HOME)/include -I$(JVM_HOME)/include/linux
CXXFLAGS  = $(INCLUDES) -c -Wall -pedantic -fPIC $(ARCH)

.PHONY: all clean


all : bld_java bld_jni bld_lib run

bld_java :
        @ echo Compiling $(JAVA_SRCS)
        @ $(JAVAC) $(JAVA_SRCS)

bld_jni :
        @ echo Building JNI Header File
        @ $(JAVAH) $(JAVA_CLAS)

bld_lib : $(CXX_OBJS)
        @ echo Building JNI Library
        @ $(CXX) -shared -o $(JNI_LIB) $^

%.o : %.cpp
        @ echo Compiling $<
        @ $(CXX) $(CXXFLAGS) $<

run :
        @ echo Running $(JAVA_CLAS)
        @ echo
        @ LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} $(JAVA) $(JAVA_CLAS)

clean :
        $(RM) $(CXX_OBJS) $(JNI_LIB)
        $(RM) $(JAVA_CLAS).class $(JAVA_CLAS).h
I hope this helps.
 
Old 01-28-2012, 10:53 PM   #10
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by dwhitney67 View Post
Through some experimentation, I was able to get the following code to work, under separate environments (32-bit and 64-bit), however I was unable to use the -m32 option on my 64-bit system; presumably this system is missing some critical development files.

Native.java:
Code:
import java.util.*;

class Native
{
   native public void function();

   static {
      System.loadLibrary("Native");
   }

   public static void main(String[] args)
   {
      try {
         Native nat = new Native();
         nat.function();
      }
      catch (Throwable e) {
         System.out.println("Java exception handled; cause: " + e);
      }
   }
}
Native.cpp:
Code:
#include <jni.h>
#include <stdexcept>
#include <string>
#include <iostream>

#include "Native.h"


class Error : public std::exception
{
public:
   Error(const std::string& message) : msg(message) {}

   virtual ~Error() throw() {}

   const char* what() const throw() { return msg.c_str(); }

private:
   std::string msg;
};


JNIEXPORT void JNICALL Java_Native_function(JNIEnv* env, jobject jobj)
{
   try
   {
      throw Error("Any error");
   }
   catch (std::exception& e)
   {
      std::cout << "C++ exception handled; cause: " << e.what() << std::endl;

      jclass exceptionClass = env->FindClass("java/lang/IllegalArgumentException");

      if (exceptionClass)
      {
         env->ThrowNew(exceptionClass, e.what());
      }
   }
}
I used the following Makefile to build and run the code:
Code:
JAVA_SRCS = Native.java
JAVA_CLAS = $(JAVA_SRCS:.java=)

CXX_SRCS  = Native.cpp
CXX_OBJS  = $(CXX_SRCS:.cpp=.o)

JNI_LIB   = libNative.so

JAVAC     = /usr/bin/javac
JAVAH     = /usr/bin/javah
JAVA      = /usr/bin/java

JVM_HOME  = /usr/lib/jvm/java-6-sun-1.6.0.26

ARCH      =
INCLUDES  = -I/usr/lib/jni -I$(JVM_HOME) -I$(JVM_HOME)/include -I$(JVM_HOME)/include/linux
CXXFLAGS  = $(INCLUDES) -c -Wall -pedantic -fPIC $(ARCH)

.PHONY: all clean


all : bld_java bld_jni bld_lib run

bld_java :
        @ echo Compiling $(JAVA_SRCS)
        @ $(JAVAC) $(JAVA_SRCS)

bld_jni :
        @ echo Building JNI Header File
        @ $(JAVAH) $(JAVA_CLAS)

bld_lib : $(CXX_OBJS)
        @ echo Building JNI Library
        @ $(CXX) -shared -o $(JNI_LIB) $^

%.o : %.cpp
        @ echo Compiling $<
        @ $(CXX) $(CXXFLAGS) $<

run :
        @ echo Running $(JAVA_CLAS)
        @ echo
        @ LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} $(JAVA) $(JAVA_CLAS)

clean :
        $(RM) $(CXX_OBJS) $(JNI_LIB)
        $(RM) $(JAVA_CLAS).class $(JAVA_CLAS).h
I hope this helps.
This is quite kind of you to do this experimentation. I really appreciate that. However, i am facing this problem because the shared library is compiled with -m32 option on 64 bit systems. You need to install glibc-devel.i686 (any version) package on your system. I too faced this issue in the begining. After this, probably you can try and run this program to replicate the issue. I will also try and do that.
 
Old 01-30-2012, 06:11 AM   #11
gaurav.rustagi
LQ Newbie
 
Registered: Jan 2012
Location: Mumbai, India
Distribution: Red Hat
Posts: 23

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by gaurav.rustagi View Post
This is quite kind of you to do this experimentation. I really appreciate that. However, i am facing this problem because the shared library is compiled with -m32 option on 64 bit systems. You need to install glibc-devel.i686 (any version) package on your system. I too faced this issue in the begining. After this, probably you can try and run this program to replicate the issue. I will also try and do that.
Hi all,

I have been able to resolve this issue. I had some .c source files where gcc is used instead of g++ for compilation. Now, It seems that i missed to have -m32 option in the configuration of make files used for .c files and i had hided warning messages with -w option in all the makefiles. As a result, i could not see what was going on during the compilation.

I have corrected these mistakes and now i can see it working fine.

Thanks for you help guys.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
segmantation fault on a 64 bit machine caused by binary compiled on a 32 bit machine ninofattore Linux - Newbie 1 10-13-2011 01:48 PM
Has anyone installed a 32-bit debian system to replace their current 64-bit system? BigVig Debian 2 06-27-2008 10:44 AM
LXer: Upgrade from 32-bit to 64-bit Fedora Linux without a system reinstall LXer Syndicated Linux News 0 01-11-2008 09:42 PM
Anyone please show me the different between the code on a 64-bit system and 32-bit ? TruongAn Programming 8 12-18-2007 08:19 AM
no sound in 32 bit chroot on 64 bit system <solved> otchie1 Linux - Software 0 11-28-2006 05:03 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:45 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration