Using Android JNI , I have created file and writing data with file descriptor.
example :-
dest = memalign( BLKSIZE, sz);
if (dest == NULL) {
LOGE("Unable to allocate memory");
return -1;
}
memcpy(dest, bufferIn, sz);
int rc = write(fd, dest, sz);
LOGI("write %d bytes.", rc);
free(dest);
if(rc == -1) {
LOGI("Error in writing : %d %s\n", errno, strerror(errno));
}
Write is successful and I can see data in file. But for each write I am getting log in adb logcat.
01-06 12:46:36.831 16292-16806/com.test.example I/io: write 1024 bytes.
01-06 12:46:36.831 16292-16806/com.test.example W/art: Attempt to remove
local handle scope entry from IRT, ignoring.
what this log mean:- I unable to understand, or what this log mean.
/W/art: Attempt to remove local handle scope entry from IRT, ignoring/
Is it something related to app need to handle.
After browsing android source code which is at
http://androidxref.com/5.1.1_r6/more/art/runtime/indirect_reference_table.cc?q=Attempt+to+remove+local+handle+scope+entry+from+IRT
I was trying delete local reference
(*env)->DeleteLocalRef(env, jbIn);
we don't need to delete local references yourself, once the JNI function returns to Java the references will get GC.
Local references will be discarded by JNI on return from a native method, but this process has nothing to do with Java garbage collection. Usually, we don't need to worry about local references.
Related
So, opcode 202 (1100 1010) is reserved for a breakpoint event according to the Java specification. I tried inserting a breakpoint opcode in a Java method with the help of the ASM library:
targetWriter.visitInsn(202);
but the JVM crashed with error message: no original bytecode found in ... at bci 0. After searching in the Hotspot implementation I found where this error is thrown:
Bytecodes::Code Method::orig_bytecode_at(int bci) const {
BreakpointInfo* bp = method_holder()->breakpoints();
for (; bp != NULL; bp = bp->next()) {
if (bp->match(this, bci)) {
return bp->orig_bytecode();
}
}
{
ResourceMark rm;
fatal(err_msg("no original bytecode found in %s at bci %d", name_and_sig_as_C_string(), bci));
}
return Bytecodes::_shouldnotreachhere;
}
So according to this, the method needs to know about the breakpoint (it stores all its breakpoints in a list) but it doesn't know about it if it is directly set via code instrumentation.
Is there a workaround (without JVMTI) to set a breakpoint event with code instrumentation?
Being a reserved opcode according to JVMS §6.2, breakpoint opcode is exclusively for the JVM internal use. It should not occur in the user generated class files.
When you inject the breakpoint instruction manually, JVM does not know what to do with it, and it does not know what original bytecode has been replaced.
Breakpoints are set with JVM TI SetBreakpoint event, and notifications are received via Breakpoint event callback. If you don't want to use JVM TI directly, the alternative is JDWP. Most Java IDEs use JDWP for debugging.
Is there any way to map a file's content into memory in Windows that does not hold a lock on the file (in particular, such that the file can be deleted while still mmap'd)?
The Java NIO libraries mmap files in Windows in such a way that the mapped file cannot be deleted while there is any non garbage collected MappedByteBuffer reference left in the heap. The JDK team claim that this is a limitation of Windows, but only when files are mmap'd, not when they are opened as regular files:
https://mail.openjdk.java.net/pipermail/nio-dev/2019-January/005698.html
(Obviously if a file is deleted while mmap'd, exactly what should happen to the mmap'd region is debatable in the world of Windows file semantics, though it's well-defined in Linux.)
For reference, the inability to delete files while they are memory mapped (or not yet garbage collected) creates a lot of problems in Java:
http://www.mapdb.org/blog/mmap_files_alloc_and_jvm_crash/
And there are security reasons why an unmap operation is not supported:
https://bugs.openjdk.java.net/browse/JDK-4724038
UPDATE: See also: How to unmap an mmap'd file by replacing with a mapping to empty pages
as noted #eryksun we can delete mapped file, if section(file mapping) was created without SEC_IMAGE attribute in 2 ways:
open file with FILE_FLAG_DELETE_ON_CLOSE flag - The file is
to be deleted immediately after all of its handles are closed, which
includes the specified handle and any other open or duplicated
handles. or we can use NtOpenFile or NtCreateFile
call with flag FILE_DELETE_ON_CLOSE.
by call ZwDeleteFile. really internal NtDeleteFile open
file with FILE_DELETE_ON_CLOSE flag and special internal
disposition DeleteOnly = TRUE. this is make call more
efficient compare normal open file and then close it handle.
in code this look like.
#ifndef FILE_SHARE_VALID_FLAGS
#define FILE_SHARE_VALID_FLAGS 0x00000007
#endif
NTSTATUS Delete1(PCWSTR FileName)
{
HANDLE hFile = CreateFile(FileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return RtlGetLastNtStatus();
}
CloseHandle(hFile);
return 0;
}
NTSTATUS Delete2(PCWSTR FileName)
{
UNICODE_STRING ObjectName;
if (RtlDosPathNameToNtPathName_U(FileName, &ObjectName, 0, 0))
{
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
NTSTATUS status = ZwDeleteFile(&oa);
RtlFreeUnicodeString(&ObjectName);
return status;
}
return STATUS_UNSUCCESSFUL;
}
note that call DeleteFileW fail here with status - STATUS_CANNOT_DELETE. i recomendate call RtlGetLastNtStatus() here instead GetLastError() because win32 mapping NTSTATUS to error code is not injective and frequently lost valuable information. say STATUS_CANNOT_DELETE mapped to ERROR_ACCESS_DENIED. but exist huge another NTSATUS codes which also mapped to ERROR_ACCESS_DENIED. the ERROR_ACCESS_DENIED not only STATUS_ACCESS_DENIED (real access denied). got STATUS_CANNOT_DELETE much more informative here compare ERROR_ACCESS_DENIED. the RtlGetLastNtStatus have exactly same signature as GetLastError and exported from ntdll.dll ( so include ntdll.lib or ntdllp.lib)
extern "C" NTSYSCALLAPI NTSTATUS NTAPI RtlGetLastNtStatus();
I use Jpcap in order to create ARP requests but when calling the method JpcapCaptor.openDevice(interface,snaplen,promisc,to_ms);, I get the following error :
java.lang.NoSuchMethodError: setPacketValue
at jpcap.JpcapCaptor.nativeOpenLive(Native Method)
at jpcap.JpcapCaptor.openDevice(JpcapCaptor.java:61)
The jpcap dll file I'm using was compiled from the source in order to work on Windows 64 bits. Is there anyway I can solve that weird problem ?
After having looked in the jpcap.dll file source code, I see that the following code is used in the openDevice method (the one that crashes) of the JpcapCaptor.java file:
JpcapCaptor jpcap = new JpcapCaptor();
String ret = jpcap.nativeOpenLive(intrface.name, snaplen, (promisc ? 1 : 0), to_ms);
According to the compiler, this is the second line of this piece of code that crashes. So I looked in the nativeOpenLive method which comes from the file JpcapCaptor.c which starts with:
JNIEXPORT jstring JNICALL
Java_jpcap_JpcapCaptor_nativeOpenLive(JNIEnv *env,jobject obj,jstring device,jint snaplen,jint promisc,jint to_ms){
char *dev;
jint id;
set_Java_env(env);
However, in this last function (set_Java_env), I found the call to the setPacketValue method in the following form: setPacketValueMID=(*env)->GetMethodID(env,Packet,"setPacketValue","(JJII)V");
Having only very weak bases in C, I would like to know the meaning of these different methods and, if possible, where the error comes from.
The source is available at the following address: https://github.com/jovigb/jpcap-x64/blob/master/src
I'm trying to use Clang via JNI (Clang C-API).
One moment after few iteractions it just stop creating new objects and crashes:
map method
0 args:
create Method instance 0x7fa26ba23c90 0x7fa26ba2a0c0 libclang: crash
detected during indexing source file: { 'source_filename' :
'/Users/asmirnov/Documents/dev/src/clang_jni/mac/test/TestFile.h'
'command_line_args' : ['-c', '-x', 'c++'], 'unsaved_files' : [],
'options' : 0, }
The code is pretty straight-forward:
mapMethod(JNIEnv *env, const CXIdxDeclInfo *info) {
debug("map method");
int numArgs = clang_Cursor_getNumArguments(info->cursor);
debug(" %i args:", numArgs);
debug("create Method instance %p %p", MethodClass, MethodConstructor);
jobject result = env->NewObject(MethodClass, MethodConstructor);
debug("create Method params instance");
Method class and constructor is found and registered as globals correctly (seems to be) and it works few iterations:
// method
MethodClass = (jclass)env->NewGlobalRef(env->FindClass("name/antonsmirnov/clang/dto/index/Method"));
debug(MethodClass != NULL ? "found MethodClass" : "not found MethodClass");
MethodConstructor = env->GetMethodID(MethodClass, "<init>", "()V");
debug(MethodConstructor != NULL ? "found MethodConstructor" : "not found MethodConstructor");
I've read some "jni tips and tricks" articles and tried to env->DeleteLocalRef and make local references count too big just to try, but no result:
// magic
jint ensureResult = env->EnsureLocalCapacity(1024);
debug("ensure result %i", ensureResult);
jint pushResult = env->PushLocalFrame(1024);
debug("push result %i", pushResult);
Clang is hijacking exception so i can't see the real reason.
The problem happens after few iterations as i said so it seems to be some limit exceeded problem or smth.
What is wrong?
UPDATE: I've done some research and i found that if i delete some local vars before then i can get one iteration more and one object instance more. So it makes me feel that it's using 16 local vars indeed and ignore my EnsureLocalCapacity invocation. Where should it be done?
Fixed using EnsureLocalCapacity in JNI_OnLoad() (did not work in each native method call).
objects created via NewObject, FindClass,needed to be freed via DeleteLocalRef(), since number of local variables are limited in jni. or you can use EnsureLocalCapacity in JNI_OnLoad().
I have an JAVA application for the fingerprint scanning and fingerprint matching.For matching the finger prints I am using the libfprint library.I have done all the settings related with the library.
The basic functions like initialization of library is work fine in the application.Now am trying to allocate the memory for the image using the function fpi_img_new() . Here is the syntax for that function
struct fp_img *fpi_img_new(size_t length);
but when I try to allocate some memory by passing the value to this function it shows the following error
GLib-ERROR **: /build/buildd/glib2.0-2.30.0/./glib/gmem.c:170: failed to allocate 3078340616 bytes
/usr/lib/jvm/java-7-openjdk/bin/java: line 31: 3078 Trace/breakpoint trap $jre $args
I am passing the value manually to just check the functionality of this function.But it gets fail.
Could any one please help me in solving the above problem?
Thank you in advance.
EDIT :
Here is my code where i am using the fpi_img_new() function :
API_EXPORTED struct fp_img *fpi_img_new(size_t length)
{
struct fp_img *img = g_malloc(sizeof(*img) + length);
memset(img, 0, sizeof(*img));
fp_dbg("length=%zd", length);
img->length = length;
return img;
}
And i am calling this function by simply passing the integer value like
fpi_img_new(2)