summaryrefslogtreecommitdiff
path: root/java/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'java/misc.c')
-rw-r--r--java/misc.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/java/misc.c b/java/misc.c
new file mode 100644
index 0000000..09d0668
--- /dev/null
+++ b/java/misc.c
@@ -0,0 +1,191 @@
+#include <string.h>
+#include <stdlib.h>
+
+#include "misc.h"
+
+bool str_starts_with (const char *haystack, const char *needle)
+{
+ int haystack_len = strlen (haystack), needle_len = strlen (needle);
+ if (haystack_len < needle_len)
+ return FALSE;
+ else
+ return memcmp (haystack, needle, needle_len * sizeof (char)) == 0;
+}
+
+void jvmti_error (jvmtiEnv *jvmti, jvmtiError error, const char *fmt, ...)
+{
+ char *errorname;
+ if ((*jvmti)->GetErrorName (jvmti, error, &errorname) != JVMTI_ERROR_NONE)
+ errorname = "<error getting error name>";
+
+ fprintf(stderr, "error (jvmtiError %d: %s): ", error, errorname);
+
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+
+ fprintf(stderr, "\n");
+}
+
+void other_error (const char *fmt, ...)
+{
+ fprintf(stderr, "error (other): ");
+
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+
+ fprintf(stderr, "\n");
+}
+
+void jvmti_dealloc (jvmtiEnv *jvmti, void *mem)
+{
+ if (mem) {
+ jvmtiError error;
+ if ((error = (*jvmti)->Deallocate (jvmti, mem)) != JVMTI_ERROR_NONE)
+ jvmti_error (jvmti, error, "Deallocate");
+ }
+}
+
+void simple_free (void *mem)
+{
+ if (mem)
+ free (mem);
+}
+
+char *get_class_name_from_sig (const char *class_sig, bool expect_class)
+{
+ int len_class_sig = strlen (class_sig);
+ if (!(class_sig[0] == 'L' && class_sig[len_class_sig - 1] == ';')) {
+ if (expect_class)
+ other_error ("don't know how to deal with class signature '%s'",
+ class_sig);
+ return NULL;
+ } else {
+ char *class_name =
+ (char*)malloc ((len_class_sig - 2 + 1) * sizeof (char));
+ int i;
+ for (i = 0; i < len_class_sig - 2; i++)
+ class_name[i] = class_sig[i + 1] == '/' ? '.' : class_sig[i + 1];
+ class_name[len_class_sig - 2] = 0;
+ return class_name;
+ }
+}
+
+/* -------------------------------------------------------------------
+
+ The only way to identify objects seems to be the JNI method
+ IsSameObject; although jobject is a pointer, the equality of two
+ jobject's does not imply the identity of the represented Java
+ objects.
+
+ Furthermore, since we only have one object at hand to get an
+ identifier needed for RTFL messages, we store all objects in a
+ list, after creating a global reference (NewGlobalRef); the index
+ in the list then identifies the object. This foils the garbage
+ collection, but for short debugging sessions, this should be
+ acceptable.
+
+ ---------------------------------------------------------------------- */
+
+static size_t reg_objects_size = 0, reg_objects_alloc_size;
+static jobject *reg_objects = NULL;
+
+size_t object_index (JNIEnv* jni, jobject object)
+{
+ size_t i;
+ for (i = 0; i < reg_objects_size; i++)
+ if ((*jni)->IsSameObject (jni, object, reg_objects[i]))
+ return i;
+
+ reg_objects_size++;
+ if (reg_objects == NULL) {
+ reg_objects_alloc_size = 1;
+ reg_objects =
+ (jobject*)malloc (reg_objects_alloc_size * sizeof (jobject));
+ } else {
+ reg_objects_alloc_size <<= 1;
+ reg_objects =
+ (jobject*)realloc (reg_objects,
+ reg_objects_alloc_size * sizeof (jobject));
+ }
+
+ i = reg_objects_size - 1;
+ reg_objects[i] = (*jni)->NewGlobalRef (jni, object);
+ return i;
+}
+
+void fill_object_buf (JNIEnv* jni, char *object_buf, jobject object)
+{
+ if (object)
+ snprintf (object_buf, SIZE_OBJECT_BUF, "%ld", object_index (jni, object));
+ else
+ strcpy (object_buf, "null");
+}
+
+// Copied from "debug_rtfl.hh".
+void rtfl_print (const char *module, const char *version,
+ const char *file, int line, const char *fmt, ...)
+{
+ // "\n" at the beginning just in case that the previous line is not
+ // finished yet.
+ printf ("\n[rtfl-%s-%s]%s:%d:pid(todo):", module, version, file, line);
+
+ va_list args;
+ va_start (args, fmt);
+
+ int i;
+ for (i = 0; fmt[i]; i++) {
+ int n, j;
+ void *p;
+ char *s;
+
+ switch (fmt[i]) {
+ case 'd':
+ n = va_arg(args, int);
+ printf ("%d", n);
+ break;
+
+ case 'p':
+ p = va_arg(args, void*);
+ printf ("%p", p);
+ break;
+
+ case 's':
+ s = va_arg (args, char*);
+ for (j = 0; s[j]; j++) {
+ if (s[j] == ':' || s[j] == '\\')
+ putchar ('\\');
+ putchar (s[j]);
+ }
+ break;
+
+ case 'q':
+ s = va_arg (args, char*);
+ for (j = 0; s[j]; j++) {
+ if (s[j] == ':' || s[j] == '\\')
+ putchar ('\\');
+ else if (s[j] == '\"')
+ printf ("\\\\"); // a quoted quoting character
+ putchar (s[j]);
+ }
+ break;
+
+ case 'c':
+ n = va_arg(args, int);
+ printf ("#%06x", n);
+ break;
+
+ default:
+ putchar (fmt[i]);
+ break;
+ }
+ }
+
+ va_end (args);
+
+ putchar ('\n');
+ fflush (stdout);
+}