< prev index next >

test/native/runtime/test_os.cpp

Print this page
rev 13549 : 8185712: [windows] Improve native symbol decoder
Reviewed-by: goetz, zgu

@@ -22,10 +22,11 @@
  */
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
 #include "unittest.hpp"
+#include "utilities/decoder.hpp"
 
 static size_t small_page_size() {
   return os::vm_page_size();
 }
 

@@ -141,10 +142,126 @@
   ASSERT_LT(t, eps) << "bad mean";
   t = (variance - 0.3355) < 0.0 ? -(variance - 0.3355) : variance - 0.3355;
   ASSERT_LT(t, eps) << "bad variance";
 }
 
+#ifdef _WIN32
+TEST(os, dll_addr_to_function_valid) {
+  char buf[128] = "";
+  int offset = -1;
+  address valid_function_pointer = (address) JNI_CreateJavaVM;
+  ASSERT_TRUE(os::dll_address_to_function_name(valid_function_pointer,
+                                          buf, sizeof(buf), &offset, true) == true);
+  ASSERT_TRUE(strstr(buf, "JNI_CreateJavaVM") != NULL);
+  ASSERT_TRUE(offset >= 0);
+}
+
+// Test that handing down a too-small output buffer will truncate the output
+// string correctly but cause no harm otherwise.
+TEST(os, dll_addr_to_function_valid_truncated) {
+  char buf[128] = "";
+  int offset = -1;
+  memset(buf, 'X', sizeof(buf));
+  address valid_function_pointer = (address) JNI_CreateJavaVM;
+  ASSERT_TRUE(os::dll_address_to_function_name(valid_function_pointer,
+                                          buf, 10, &offset, true) == true);
+  ASSERT_TRUE(buf[10 - 1] == '\0');
+  ASSERT_TRUE(buf[10] == 'X');
+  // Note: compare the first (sizeof buf - 2) bytes only because Windows decoder
+  // (actually UndecorateSymbolName()) seems to have a bug where it uses one byte less than
+  // the buffer would offer.
+  ASSERT_TRUE(strncmp(buf, "JNI_Crea", 8) == 0);
+  ASSERT_TRUE(offset >= 0);
+}
+
+// Test that handing down invalid addresses will cause no harm and output buffer
+// and offset will contain "" and -1, respectively.
+TEST(os, dll_addr_to_function_invalid) {
+  char buf[128];
+  int offset;
+  address invalid_function_pointers[] = { NULL, (address)1, (address)&offset };
+
+  for (int i = 0;
+       i < sizeof(invalid_function_pointers) / sizeof(address);
+       i ++)
+  {
+    address addr = invalid_function_pointers[i];
+    strcpy(buf, "blabla");
+    offset = 12;
+    ASSERT_TRUE(os::dll_address_to_function_name(addr, buf, sizeof(buf),
+                                            &offset, true) == false);
+    ASSERT_TRUE(buf[0] == '\0');
+    ASSERT_TRUE(offset == -1);
+  }
+}
+
+TEST(os, decoder_get_source_info_valid) {
+  char buf[128] = "";
+  int line = -1;
+  address valid_function_pointer = (address) JNI_CreateJavaVM;
+  ASSERT_TRUE(Decoder::get_source_info(valid_function_pointer, buf, sizeof(buf), &line) == true);
+  ASSERT_TRUE(strcmp(buf, "jni.cpp") == 0);
+  ASSERT_TRUE(line >= 0);
+}
+
+// Test that handing down a too-small output buffer will truncate the output
+// string correctly but cause no harm otherwise.
+TEST(os, decoder_get_source_info_valid_truncated) {
+  char buf[128] = "";
+  int line = -1;
+  memset(buf, 'X', sizeof(buf));
+  address valid_function_pointer = (address) JNI_CreateJavaVM;
+  ASSERT_TRUE(Decoder::get_source_info(valid_function_pointer, buf, 7, &line) == true);
+  ASSERT_TRUE(buf[7 - 1] == '\0');
+  ASSERT_TRUE(buf[7] == 'X');
+  ASSERT_TRUE(strcmp(buf, "jni.cp") == 0);
+  ASSERT_TRUE(line > 0);
+}
+
+// Test that handing down invalid addresses will cause no harm and output buffer
+// and line will contain "" and -1, respectively.
+TEST(os, decoder_get_source_info_invalid) {
+  char buf[128] = "";
+  int line = -1;
+  address invalid_function_pointers[] = { NULL, (address)1, (address)&line };
+
+  for (int i = 0;
+       i < sizeof(invalid_function_pointers) / sizeof(address);
+       i ++)
+  {
+    address addr = invalid_function_pointers[i];
+    // We should fail but not crash
+    strcpy(buf, "blabla");
+    line = 12;
+    ASSERT_TRUE(Decoder::get_source_info(addr, buf, sizeof(buf), &line) == false);
+    // buffer should contain "", offset should contain -1
+    ASSERT_TRUE(buf[0] == '\0');
+    ASSERT_TRUE(line == -1);
+  }
+}
+
+#ifdef PLATFORM_PRINT_NATIVE_STACK
+TEST(os, platform_print_native_stack) {
+  bufferedStream bs;
+  // Note: scratch buffer argument to os::platform_print_native_stack is not
+  // optional!
+  char scratch_buffer [255];
+  for (int i = 0; i < 3; i ++) {
+    ASSERT_TRUE(os::platform_print_native_stack(&bs, NULL, scratch_buffer,
+                                                sizeof(scratch_buffer)));
+    ASSERT_TRUE(bs.size() > 0);
+    // This may depend on debug information files being generated and available
+    // (e.g. not zipped).
+    ASSERT_TRUE(::strstr(bs.base(), "platform_print_native_stack") != NULL);
+#ifdef _WIN32
+    // We have source information on Windows.
+    ASSERT_TRUE(::strstr(bs.base(), "os_windows_x86.cpp") != NULL);
+#endif
+  }
+}
+#endif
+#endif
 
 #ifdef ASSERT
 TEST_VM_ASSERT_MSG(os, page_size_for_region_with_zero_min_pages, "sanity") {
   size_t region_size = 16 * os::vm_page_size();
   os::page_size_for_region_aligned(region_size, 0); // should assert
< prev index next >