[Lldb-commits] [lldb] bad6154 - [Reproducers] Serialize process arguments in ProcessInfo
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Tue May 12 11:12:44 PDT 2020
Author: Jonas Devlieghere
Date: 2020-05-12T11:12:37-07:00
New Revision: bad61548b2074cf3bf7be2cb4c0d75646e001a73
URL: https://github.com/llvm/llvm-project/commit/bad61548b2074cf3bf7be2cb4c0d75646e001a73
DIFF: https://github.com/llvm/llvm-project/commit/bad61548b2074cf3bf7be2cb4c0d75646e001a73.diff
LOG: [Reproducers] Serialize process arguments in ProcessInfo
While debugging why TestProcessList.py failed during passive replay, I
remembered that we don't serialize the arguments for ProcessInfo. This
is necessary to make the test pass and to make platform process list -v
behave the same during capture and replay.
Differential revision: https://reviews.llvm.org/D79646
Added:
lldb/test/Shell/Reproducer/TestProcessList.test
Modified:
lldb/include/lldb/Utility/Args.h
lldb/source/Utility/Args.cpp
lldb/source/Utility/ProcessInfo.cpp
lldb/unittests/Utility/ArgsTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Utility/Args.h b/lldb/include/lldb/Utility/Args.h
index 1308f4038dbd..560f25795d3b 100644
--- a/lldb/include/lldb/Utility/Args.h
+++ b/lldb/include/lldb/Utility/Args.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/YAMLTraits.h"
#include <string>
#include <utility>
#include <vector>
@@ -34,6 +35,9 @@ class Args {
struct ArgEntry {
private:
friend class Args;
+ friend struct llvm::yaml::MappingTraits<Args>;
+ friend struct llvm::yaml::MappingTraits<Args::ArgEntry>;
+
std::unique_ptr<char[]> ptr;
char quote;
@@ -283,6 +287,8 @@ class Args {
char quote_char);
private:
+ friend struct llvm::yaml::MappingTraits<Args>;
+
std::vector<ArgEntry> m_entries;
std::vector<char *> m_argv;
};
@@ -373,4 +379,28 @@ class OptionsWithRaw {
} // namespace lldb_private
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<lldb_private::Args::ArgEntry> {
+ class NormalizedArgEntry {
+ public:
+ NormalizedArgEntry(IO &) {}
+ NormalizedArgEntry(IO &, lldb_private::Args::ArgEntry &entry)
+ : value(entry.ref()), quote(entry.quote) {}
+ lldb_private::Args::ArgEntry denormalize(IO &) {
+ return lldb_private::Args::ArgEntry(value, quote);
+ }
+ StringRef value;
+ char quote;
+ };
+ static void mapping(IO &io, lldb_private::Args::ArgEntry &v);
+};
+template <> struct MappingTraits<lldb_private::Args> {
+ static void mapping(IO &io, lldb_private::Args &v);
+};
+} // namespace yaml
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::Args::ArgEntry)
+
#endif // LLDB_UTILITY_ARGS_H
diff --git a/lldb/source/Utility/Args.cpp b/lldb/source/Utility/Args.cpp
index 443f9bf37cc4..27dcbb822910 100644
--- a/lldb/source/Utility/Args.cpp
+++ b/lldb/source/Utility/Args.cpp
@@ -684,3 +684,20 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) {
m_suffix = std::string(original_args);
}
}
+
+void llvm::yaml::MappingTraits<Args::ArgEntry>::mapping(IO &io,
+ Args::ArgEntry &v) {
+ MappingNormalization<NormalizedArgEntry, Args::ArgEntry> keys(io, v);
+ io.mapRequired("value", keys->value);
+ io.mapRequired("quote", keys->quote);
+}
+
+void llvm::yaml::MappingTraits<Args>::mapping(IO &io, Args &v) {
+ io.mapRequired("entries", v.m_entries);
+
+ // Recompute m_argv vector.
+ v.m_argv.clear();
+ for (auto &entry : v.m_entries)
+ v.m_argv.push_back(entry.data());
+ v.m_argv.push_back(nullptr);
+}
diff --git a/lldb/source/Utility/ProcessInfo.cpp b/lldb/source/Utility/ProcessInfo.cpp
index 9a29218f7f1d..aae48d6a4872 100644
--- a/lldb/source/Utility/ProcessInfo.cpp
+++ b/lldb/source/Utility/ProcessInfo.cpp
@@ -337,6 +337,7 @@ void llvm::yaml::MappingTraits<ProcessInstanceInfo>::mapping(
IO &io, ProcessInstanceInfo &Info) {
io.mapRequired("executable", Info.m_executable);
io.mapRequired("arg0", Info.m_arg0);
+ io.mapRequired("args", Info.m_arguments);
io.mapRequired("arch", Info.m_arch);
io.mapRequired("uid", Info.m_uid);
io.mapRequired("gid", Info.m_gid);
diff --git a/lldb/test/Shell/Reproducer/TestProcessList.test b/lldb/test/Shell/Reproducer/TestProcessList.test
new file mode 100644
index 000000000000..200dcb3febe7
--- /dev/null
+++ b/lldb/test/Shell/Reproducer/TestProcessList.test
@@ -0,0 +1,21 @@
+# UNSUPPORTED: system-freebsd
+
+# Test that ProcessInfo is correctly serialized by comparing the output of
+# 'platform process list -v' during capture and replay. The test assumes that
+# there's at least two processes.
+
+# RUN: %lldb -x -b -o 'platform process list -v' -o 'reproducer generate' --capture --capture-path %t.repro > %t.log
+# RUN: %lldb --replay %t.repro >> %t.log
+# RUN: cat %t.log | FileCheck %s
+
+# CHECK: [[PROCS:[0-9]+]] matching processes were found
+# CHECK: PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE ARGUMENTS
+# CHECK-NEXT: ====== ====== ========== ========== ========== ========== ============================== ============================
+# CHECK-NEXT: [[PID0:[0-9]+]] [[PROC0:.*]]
+# CHECK-NEXT: [[PID1:[0-9]+]] [[PROC1:.*]]
+# CHECK: Reproducer written to
+# CHECK: [[PROCS]] matching processes were found
+# CHECK: PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE ARGUMENTS
+# CHECK-NEXT: ====== ====== ========== ========== ========== ========== ============================== ============================
+# CHECK-NEXT: [[PID0]] [[PROC0]]
+# CHECK-NEXT: [[PID1]] [[PROC1]]
diff --git a/lldb/unittests/Utility/ArgsTest.cpp b/lldb/unittests/Utility/ArgsTest.cpp
index bfbd2ccfdf7b..ed1235f99c71 100644
--- a/lldb/unittests/Utility/ArgsTest.cpp
+++ b/lldb/unittests/Utility/ArgsTest.cpp
@@ -282,3 +282,34 @@ TEST(ArgsTest, ReplaceArgumentAtIndexFarOutOfRange) {
EXPECT_EQ(3u, args.GetArgumentCount());
EXPECT_STREQ(args.GetArgumentAtIndex(2), "b");
}
+
+TEST(ArgsTest, Yaml) {
+ std::string buffer;
+ llvm::raw_string_ostream os(buffer);
+
+ // Serialize.
+ Args args;
+ args.SetCommandString("this 'has' \"multiple\" args");
+ llvm::yaml::Output yout(os);
+ yout << args;
+ os.flush();
+
+ llvm::outs() << buffer;
+
+ // Deserialize.
+ Args deserialized;
+ llvm::yaml::Input yin(buffer);
+ yin >> deserialized;
+
+ EXPECT_EQ(4u, deserialized.GetArgumentCount());
+ EXPECT_STREQ(deserialized.GetArgumentAtIndex(0), "this");
+ EXPECT_STREQ(deserialized.GetArgumentAtIndex(1), "has");
+ EXPECT_STREQ(deserialized.GetArgumentAtIndex(2), "multiple");
+ EXPECT_STREQ(deserialized.GetArgumentAtIndex(3), "args");
+
+ llvm::ArrayRef<Args::ArgEntry> entries = deserialized.entries();
+ EXPECT_EQ(entries[0].GetQuoteChar(), '\0');
+ EXPECT_EQ(entries[1].GetQuoteChar(), '\'');
+ EXPECT_EQ(entries[2].GetQuoteChar(), '"');
+ EXPECT_EQ(entries[3].GetQuoteChar(), '\0');
+}
More information about the lldb-commits
mailing list