JVM crashes unexpectedly from time to time in our servers with SIGSEGV. We are using JNI to call some C functions which eventually use ECPG to talk to postgres db.
Here is a stack trace for reference:
Stack: [0xa895e000,0xa89af000], sp=0xa89ab550, free space=309k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libpq.so.5+0x1a42c] resetPQExpBuffer+0x2c
C [libpq.so.5+0x1a46f] printfPQExpBuffer+0x1f
C [libpq.so.5+0x10b1a] PQgetResult+0xea
C [libpq.so.5+0x10c97]
C [libpq.so.5+0x110e7] PQexec+0x27
C [libecpg.so.6+0x506f] ECPGdo+0xc5f
C [libvcswsilib.so+0x9b914] get_codes_info+0x4eb
C [libvcswsilib.so+0x4b4c8] getCodes(CConference*, CUser const&)+0xc8
C [libvcswsilib.so+0x4d06d] CConf::GetFromDatabase(CUser const&, std::string const&)+0x203
C [libvcswsilib.so+0x4ce0f] CConf::GetFromDatabaseViaEitherCode(CUser const&, std::string const&)+0xd7
C [libvcswsilib.so+0x3acac] getCommon(CUser&, std::string const&, std::string&)+0x45
C [libvcswsilib.so+0x3b56e] getCred(std::string const&, std::string&)+0x107
C [libvcswsilib.so+0x376fa] WebServiceImpl_getCredJNI+0x78
j WebServiceImpl.getCredJNI(Ljava/lang/String;)Ljava/lang/String;+0
j WebServiceImpl.getInfo(Ljava/net/InetSocketAddress;Lcom/Lis tener;Ljava/util/HashMap;)Ljava/lang/String;+51
j MessageProcessor.processInfo(Lcom/wss/MessageProcessor$MessagePacket;)V+47
j MessageProcessor.processMessage(Lcom/wss/Manager$MessagePacket;Ljava/lang/String;)V+79
J 388% C2 Manager.run()V (257 bytes) # 0xf4737b9c [0xf47370c0+0xadc]
j java.lang.Thread.run()V+11
v ~StubRoutines::call_stub
V [libjvm.so+0x459d54]
V [libjvm.so+0x61b129]
V [libjvm.so+0x45923a]
V [libjvm.so+0x45936b]
V [libjvm.so+0x4a4ffc]
V [libjvm.so+0x73b040]
V [libjvm.so+0x73b339]
V [libjvm.so+0x622689]
C [libpthread.so.0+0x6b39] start_thread+0xc9
We have scanned through the native and Java code and didn't find anything which might be leading to this issue. Don't have much idea on the working of ECPG or postgres.
Any kind of help/idea for debugging the issue will be much appreciated.
Related
I have following c++ code
int myvar=1;
void test1( int j)
{
int b=j+1;
}
void main()
{
myvar=2;
test1(50);
myvar=3;
test1(100);
myvar=6;
test1(200);
}
I'm trying to set a breakpoint that stops if myvar is greater than 4 when running function test1.
Here is my breakpoint:
bp test!test1 ".if ( poi(myvar)>0n4) {} .else {gc} "
however, it stops every time test1 is executed...
The executable file is called test.exe, a 64 bit application.
Any suggestion would be appreciated.
A little bit of debugging in the breakpoint reveals what is happening:
0 e Disable Clear 00007ff6`77e11410 [f:\projects\windbg_help\main.cpp # 4] 0001 (0001) 0:**** windbg_help!test1 "?? myvar; r $t1=myvar; ?? #$t1; r $t2=poi(myvar); ?? #$t2; .if (dwo(myvar) > 0n4) {.echo yes; gc} .else {.echo no; gc} "
I set the t1 temp register to myvar, and t2 temp register to the contents of myvar, then display them:
0:000> g
int 0n2
unsigned int64 0x00007ff6`77e1c000
unsigned int64 0xffffffff`00000002
no
int 0n3
unsigned int64 0x00007ff6`77e1c000
unsigned int64 0xffffffff`00000003
no
int 0n6
unsigned int64 0x00007ff6`77e1c000
unsigned int64 0xffffffff`00000006
yes
ModLoad: 00007ff9`c8520000 00007ff9`c8531000 C:\WINDOWS\System32\kernel.appcore.dll
ModLoad: 00007ff9`c9da0000 00007ff9`c9e3e000 C:\WINDOWS\System32\msvcrt.dll
ModLoad: 00007ff9`c9aa0000 00007ff9`c9bc2000 C:\WINDOWS\System32\RPCRT4.dll
ntdll!NtTerminateProcess+0x14:
00007ff9`cc5cfcd4 c3 ret
Notice how poi(myvar) is returning a 64bit value, and the upper 32bits are set. You poi(myvar) > 0n4 comparison is saying:
if (0xffffffff0000000? > 4) then { always true }
use dwo(myvar) instead to read only the 32bit contents
I am trying to add two 8 bit number and wrote the following code:
MVI D 08h
MVI B 03h
MVI C 00h
MOV A D
LOOP: CMP B
JC DOWN
INR A
SUB B
JNZ LOOP
DOWN: HLT
But I got incorrect output.
Well assuming my assumption is correct that you are storing answer in C,
then just do a small change on 7th line:
MVI D 08h
MVI B 03h
MVI C 00h
MOV A D
LOOP: CMP B
JC DOWN
INR C
SUB B
JNZ LOOP
DOWN: HLT
It should work now.
I'm trying to manipulate guid from C++. Whenever I attempt to serialize a guid, I get a null pointer.
U g={0};
auto k = ku(g);
auto p = ::b9(2, k);
First two lines are straight from the manual for creating a null guid. This will result in p == 0.
Really what I was attempting to do was creating a list of guid and then serializing:
k = ktn(UU, 3)
kU(k)[0] = <an instance of U with the g bytes initialized>
kU(k)[1] = <an instance of U with the g bytes initialized>
kU(k)[2] = <an instance of U with the g bytes initialized>
That did not work when attempting to serialize.
I believe you should be using 3 as the first argument to b9. For example:
jmcmurray#homer ~/c $ more test.c
#include"k.h"
K f(K x)
{
K k = ktn(UU,3);I j=0;
for(j=0;j<3;j++){
U g={0};I i=0;
for(i=j;i<j+16;i++){
g.g[i] = (unsigned char)i;
}
kU(k)[0] = g;
}
return b9(3,k);
}
jmcmurray#homer ~/c $ gcc -shared -fPIC -DKXVER=3 test.c -o test.so
jmcmurray#homer ~/c $ q
KDB+ 3.5 2017.11.30 Copyright (C) 1993-2017 Kx Systems
l64/ 8()core 16048MB jmcmurray homer.aquaq.co.uk 192.168.1.57 EXPIRE 2019.06.30 AquaQ #52428
q)f:`:./test 2:(`f;1)
q)f[]
0x010000003e000000020003000000000002030405060708090a0b0c0d0e0f00ae67af727f000..
q)-9!f[]
00000203-0405-0607-0809-0a0b0c0d0e0f 001868af-727f-0000-6062-67af727f0000 a0a..
q)
Here I am able to return a serialised list of GUIDs from my shared object & deserialize on the q side. When I tried with 2 as in your example I got a 'type error when running the function in q.
According to https://code.kx.com/q/interfaces/capiref/#b9-serialize 3 means
unenumerate, compress, allow serialization of timespan and timestamp
2 is the same without "compress". So I guess you must compress GUIDs?
I am writing this F90 program to compute a function in fortran which takes the input from a .mat file and save the results in another .mat file.
I followed this answer to get the code compiled and correctly linked. This is my makefile command:
gfortran -g -fcheck=all binhkorn_mat.F90 -I/usr/local/MATLAB/R2015b/extern/include/ -L/usr/local/MATLAB/R2015b/bin/glnxa64 -cpp -o binhkorn_mat -lmat -lmx -Wl,-rpath /usr/local/MATLAB/R2015b/bin/glnxa64/
The output file is apparently correctly compiled, but then once I run the program the following SF appears (I'm working on LINUX Ubuntu 14.04 LTS):
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7FD650063F27
#1 0x7FD6500644F4
#2 0x7FD64FCBCD3F
#3 0x7FD64FDD7AF6
#4 0x400A3F in binhkorn_mat at binhkorn_mat.F90:17 (discriminator 2)
./binhkorn_mat: Segmentation fault
I can't figure out if there's an error with the compiler or if I did something wrong with the pointers/functions definitions. Here's the code (binhkorn_mat.F90):
#include "fintrf.h"
PROGRAM binhkorn_mat
IMPLICIT NONE
mwPointer matOpen, matGetVariable, matPutVariable
mwPointer mpin, mpX, mpout, mpcf
INTEGER :: i,j
REAL*8, DIMENSION(2) :: x
REAL*8, DIMENSION(4) :: cf
!input/output through .mat f
mpin = matOpen('X.mat', 'u')
mpX = matGetVariable(mpin, 'X')
CALL mxCopyPtrToReal8(mpX, x, 2)
CALL matClose(mpin)
!fitness functions
cf(1) = ((x(1)-2)**2 + (x(2)-1)**2 + 2)
cf(2) = (9*x(1) + (x(2)-1)**2)
!constraints
cf(3) = x(1)*x(1) + x(2)*x(2) - 225
cf(4) = x(1) - 3*x(2) + 10
!output file created
CALL mxCopyReal8ToPtr(cf, mpcf, 4)
mpout = matOpen('cf.mat', 'w')
mpcf = matPutVariable(mpout, 'cf', mpcf)
CALL matClose(mpout)
END PROGRAM
The X.mat file is correctly created by an external Matlab script and contains a variable named X which is a 2-element row vector.
I basically misunderstood how to use of many functions. The pointers i supplied as input to some of them were not the correct ones. I post here the working solution:
#include "fintrf.h"
PROGRAM binhkorn_mat
IMPLICIT NONE
mwPointer matOpen, matGetVariable!, matPutVariable
mwPointer mxGetData, mxGetNumberOfElements, mxCreateNumericArray
mwPointer mpin, mpX, mpout, mpcf
mwSize ndim
mwSize dims(2)
INTEGER :: s
INTEGER*4 mxClassIDFromClassName
CHARACTER (LEN = 6) :: classname
REAL*8, DIMENSION(2) :: x
REAL*8, DIMENSION(4) :: cf
!input/output through .mat f
mpin = matOpen('X.mat', 'r')
mpX = matGetVariable(mpin, 'X')
CALL mxCopyPtrToReal8(mxGetData(mpX), x, mxGetNumberOfElements(mpX))
!CALL matClose(mpin)
!fitness functions
cf(1) = ((x(1)-2)**2 + (x(2)-1)**2 + 2)
cf(2) = (9*x(1) + (x(2)-1)**2)
!constraints
cf(3) = x(1)*x(1) + x(2)*x(2) - 225
cf(4) = x(1) - 3*x(2) + 10
!output .mat file created and filled
s = size(cf)
ndim = 2
classname = 'double'
dims(1) = 1
dims(2) = s
mpcf = mxCreateNumericArray(ndim, dims, mxClassIDFromClassName(classname), 0)
CALL mxCopyReal8ToPtr(cf, mxGetData(mpcf), mxGetNumberOfElements(mpcf))
mpout = matOpen('cf.mat', 'w')
CALL matPutVariable(mpout, 'cf', mpcf)
!CALL matClose(mpout)
END PROGRAM
I am trying to use unicode variable names in g++.
It does not appear to work.
Does g++ not support unicode variable names, ... or is there some subset of unicode (from which I'm not testing in).
Thanks!
You have to specify the -fextended-identifiers flag when compiling, you also have to use \uXXXX or \uXXXXXXXX for unicode(atleast in gcc it's unicode)
Identifiers (variable/class names etc) in g++ can't be of utf-8/utf-16 or whatever encoding,
they have to be:
identifier:
nondigit
identifier nondigit
identifier digit
a nondigit is
nondigit: one of
universalcharactername
_ a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
and a universalcharactername is
universalcharactername:
\UXXXXXXXX
\uXXXX
Thus, if you save your source file as UTF-8, you cannot have a variable like e.g.:
int høyde = 10;
it had to be written like:
int h\u00F8yde = 10;
(which imo would beat the whole purpose - so just stick with a-z)
A one-line patch to the cpp preprocessor allows UTF-8 input. Details for gcc are given at
https://www.raspberrypi.org/forums/viewtopic.php?p=802657
however, since the preprocessor is shared, the same patch should work for g++ as well. In particular, the patch needed, as of gcc-5.2 is
diff -cNr gcc-5.2.0/libcpp/charset.c gcc-5.2.0-ejo/libcpp/charset.c
*** gcc-5.2.0/libcpp/charset.c Mon Jan 5 04:33:28 2015
--- gcc-5.2.0-ejo/libcpp/charset.c Wed Aug 12 14:34:23 2015
***************
*** 1711,1717 ****
struct _cpp_strbuf to;
unsigned char *buffer;
! input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset);
if (input_cset.func == convert_no_conversion)
{
to.text = input;
--- 1711,1717 ----
struct _cpp_strbuf to;
unsigned char *buffer;
! input_cset = init_iconv_desc (pfile, "C99", input_charset);
if (input_cset.func == convert_no_conversion)
{
to.text = input;
Note that for the above patch to work, a recent version of iconv needs to be installed that supports C99 conversions. Type iconv --list to verify this, otherwise, you can install a new version of iconv along with gcc as described in the link above. Change the configure command to
$ ../gcc-5.2.0/configure -v --disable-multilib \
--with-libiconv-prefix=/usr/local/gcc-5.2 \
--prefix=/usr/local/gcc-5.2 \
--enable-languages="c,c++"
if you are building for x86 and want to include the c++ compiler as well.