[lib/debugger_utils] New function GetObjectName
Tested: New testcase added
Change-Id: I2d74ce03543539ce9fc0f997ce1f38b0bfec55af
diff --git a/garnet/lib/debugger_utils/util.h b/garnet/lib/debugger_utils/util.h
index 8aa6d2f..a701436 100644
--- a/garnet/lib/debugger_utils/util.h
+++ b/garnet/lib/debugger_utils/util.h
@@ -103,6 +103,12 @@
// Convenience wrapper that takes an object.
zx_koid_t GetRelatedKoid(const zx::object_base& object);
+// Return the ZX_PROP_NAME property of |handle|.
+// Returns "" if the object doesn't have a name (not all objects have names).
+std::string GetObjectName(zx_handle_t handle);
+// Convenience wrapper that takes an object.
+std::string GetObjectName(const zx::object_base& object);
+
// Return the name of exception |type| as a C string.
// Returns nullptr if |type| is invalid.
// This does not take a |zx_excp_type_t| value because it also handles
diff --git a/garnet/lib/debugger_utils/util_zx.cc b/garnet/lib/debugger_utils/util_zx.cc
index 7c78d72..63825d4 100644
--- a/garnet/lib/debugger_utils/util_zx.cc
+++ b/garnet/lib/debugger_utils/util_zx.cc
@@ -47,6 +47,20 @@
return GetRelatedKoid(object.get());
}
+std::string GetObjectName(zx_handle_t handle) {
+ char name[ZX_MAX_NAME_LEN];
+ zx_status_t status = zx_object_get_property(handle, ZX_PROP_NAME,
+ name, sizeof(name));
+ if (status < 0) {
+ return "";
+ }
+ return name;
+}
+
+std::string GetObjectName(const zx::object_base& object) {
+ return GetObjectName(object.get());
+}
+
std::string ZxErrorString(zx_status_t status) {
return fxl::StringPrintf("%s(%d)", zx_status_get_string(status), status);
}
diff --git a/garnet/lib/debugger_utils/util_zx_unittest.cc b/garnet/lib/debugger_utils/util_zx_unittest.cc
index 7154e9b..00312fb 100644
--- a/garnet/lib/debugger_utils/util_zx_unittest.cc
+++ b/garnet/lib/debugger_utils/util_zx_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <zx/event.h>
+#include <zx/socket.h>
#include <lib/fdio/spawn.h>
@@ -47,5 +48,31 @@
EXPECT_EQ(GetRelatedKoid(process.get()), GetKoid(job.get()));
}
+TEST(UtilZx, GetObjectName) {
+ zx_handle_t self = zx_thread_self();
+ static const char name[] = "GetObjectNameTest";
+ ASSERT_EQ(zx_object_set_property(self, ZX_PROP_NAME, name, sizeof(name)),
+ ZX_OK);
+ ASSERT_STREQ(GetObjectName(self).c_str(), name);
+}
+
+TEST(UtilZx, GetNoNameObjectName) {
+ // Events don't have names, but also don't have properties,
+ // so we'll get ACCESS_DENIED.
+ zx::event event;
+ EXPECT_EQ(zx::event::create(0u, &event), ZX_OK);
+ static const char name[] = "GetNoNameObjectNameTest";
+ ASSERT_EQ(event.set_property(ZX_PROP_NAME, name, sizeof(name)),
+ ZX_ERR_ACCESS_DENIED);
+ ASSERT_STREQ(GetObjectName(event).c_str(), "");
+
+ // Sockets have properties but not names, so we'll get NOT_SUPPORTED.
+ zx::socket socket0, socket1;
+ EXPECT_EQ(zx::socket::create(0u, &socket0, &socket1), ZX_OK);
+ ASSERT_EQ(socket0.set_property(ZX_PROP_NAME, name, sizeof(name)),
+ ZX_ERR_NOT_SUPPORTED);
+ ASSERT_STREQ(GetObjectName(socket0).c_str(), "");
+}
+
} // namespace
} // namespace debugger_utils