Merge "simpleperf: update simpleperf prebuilts to build 4737280."
diff --git a/ext4_utils/mkuserimg_mke2fs.sh b/ext4_utils/mkuserimg_mke2fs.sh
index ea73ff7..1d5c0af 100755
--- a/ext4_utils/mkuserimg_mke2fs.sh
+++ b/ext4_utils/mkuserimg_mke2fs.sh
@@ -8,7 +8,7 @@
mkuserimg.sh [-s] SRC_DIR OUTPUT_FILE EXT_VARIANT MOUNT_POINT SIZE [-j <journal_size>]
[-T TIMESTAMP] [-C FS_CONFIG] [-D PRODUCT_OUT] [-B BLOCK_LIST_FILE]
[-d BASE_ALLOC_FILE_IN ] [-A BASE_ALLOC_FILE_OUT ] [-L LABEL]
- [-i INODES ] [-e ERASE_BLOCK_SIZE] [-o FLASH_BLOCK_SIZE]
+ [-i INODES ] [-M RSV_PCT] [-e ERASE_BLOCK_SIZE] [-o FLASH_BLOCK_SIZE]
[-U MKE2FS_UUID] [-S MKE2FS_HASH_SEED] [FILE_CONTEXTS]
EOT
}
@@ -94,6 +94,11 @@
shift; shift
fi
+if [[ "$1" == "-M" ]]; then
+ MKE2FS_OPTS+=" -m $2"
+ shift; shift
+fi
+
if [[ "$1" == "-e" ]]; then
if [[ $MKE2FS_EXTENDED_OPTS ]]; then
MKE2FS_EXTENDED_OPTS+=","
diff --git a/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl b/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl
index f022dbf..5fdc09a 100644
--- a/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl
+++ b/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl
@@ -21,8 +21,11 @@
/**
* Start continuous profiling with the given parameters.
*/
- void startProfiling(int profilingDuration, int profilingInterval,
- int iterations);
+ void startProfiling(int collectionInterval, int iterations,
+ int process, int samplingPeriod, int samplingFrequency,
+ int sampleDuration, boolean stackProfile,
+ boolean useElfSymbolizer, boolean sendToDropbox);
+
/**
* Start profiling with the parameters in the given protobuf.
*/
diff --git a/perfprofd/binder_interface/perfprofd_binder.cc b/perfprofd/binder_interface/perfprofd_binder.cc
index 5339440..cbb3fce 100644
--- a/perfprofd/binder_interface/perfprofd_binder.cc
+++ b/perfprofd/binder_interface/perfprofd_binder.cc
@@ -66,9 +66,15 @@
status_t dump(int fd, const Vector<String16> &args) override;
- Status startProfiling(int32_t profilingDuration,
- int32_t profilingInterval,
- int32_t iterations) override;
+ Status startProfiling(int32_t collectionInterval,
+ int32_t iterations,
+ int32_t process,
+ int32_t samplingPeriod,
+ int32_t samplingFrequency,
+ int32_t sampleDuration,
+ bool stackProfile,
+ bool useElfSymbolizer,
+ bool sendToDropbox) override;
Status startProfilingProtobuf(const std::vector<uint8_t>& config_proto) override;
Status stopProfiling() override;
@@ -105,15 +111,39 @@
return NO_ERROR;
}
-Status PerfProfdNativeService::startProfiling(int32_t profilingDuration,
- int32_t profilingInterval,
- int32_t iterations) {
+Status PerfProfdNativeService::startProfiling(int32_t collectionInterval,
+ int32_t iterations,
+ int32_t process,
+ int32_t samplingPeriod,
+ int32_t samplingFrequency,
+ int32_t sampleDuration,
+ bool stackProfile,
+ bool useElfSymbolizer,
+ bool sendToDropbox) {
auto config_fn = [&](ThreadedConfig& config) {
config = ThreadedConfig(); // Reset to a default config.
- config.sample_duration_in_s = static_cast<uint32_t>(profilingDuration);
- config.collection_interval_in_s = static_cast<uint32_t>(profilingInterval);
- config.main_loop_iterations = static_cast<uint32_t>(iterations);
+ if (collectionInterval >= 0) {
+ config.collection_interval_in_s = collectionInterval;
+ }
+ if (iterations >= 0) {
+ config.main_loop_iterations = iterations;
+ }
+ if (process >= 0) {
+ config.process = process;
+ }
+ if (samplingPeriod > 0) {
+ config.sampling_period = samplingPeriod;
+ }
+ if (samplingFrequency > 0) {
+ config.sampling_frequency = samplingFrequency;
+ }
+ if (sampleDuration > 0) {
+ config.sample_duration_in_s = sampleDuration;
+ }
+ config.stack_profile = stackProfile;
+ config.use_elf_symbolizer = useElfSymbolizer;
+ config.send_to_dropbox = sendToDropbox;
};
std::string error_msg;
if (!StartProfiling(config_fn, &error_msg)) {
diff --git a/simpleperf/IOEventLoop.cpp b/simpleperf/IOEventLoop.cpp
index 662aba2..01f2acd 100644
--- a/simpleperf/IOEventLoop.cpp
+++ b/simpleperf/IOEventLoop.cpp
@@ -37,7 +37,8 @@
}
};
-IOEventLoop::IOEventLoop() : ebase_(nullptr), has_error_(false), use_precise_timer_(false) {}
+IOEventLoop::IOEventLoop()
+ : ebase_(nullptr), has_error_(false), use_precise_timer_(false), in_loop_(false) {}
IOEventLoop::~IOEventLoop() {
events_.clear();
@@ -163,8 +164,10 @@
}
bool IOEventLoop::RunLoop() {
+ in_loop_ = true;
if (event_base_dispatch(ebase_) == -1) {
LOG(ERROR) << "event_base_dispatch() failed";
+ in_loop_ = false;
return false;
}
if (has_error_) {
@@ -174,9 +177,12 @@
}
bool IOEventLoop::ExitLoop() {
- if (event_base_loopbreak(ebase_) == -1) {
- LOG(ERROR) << "event_base_loopbreak() failed";
- return false;
+ if (in_loop_) {
+ if (event_base_loopbreak(ebase_) == -1) {
+ LOG(ERROR) << "event_base_loopbreak() failed";
+ return false;
+ }
+ in_loop_ = false;
}
return true;
}
diff --git a/simpleperf/IOEventLoop.h b/simpleperf/IOEventLoop.h
index 9dc73c3..4a84197 100644
--- a/simpleperf/IOEventLoop.h
+++ b/simpleperf/IOEventLoop.h
@@ -85,6 +85,7 @@
std::vector<std::unique_ptr<IOEvent>> events_;
bool has_error_;
bool use_precise_timer_;
+ bool in_loop_;
};
#endif // SIMPLE_PERF_IOEVENT_LOOP_H_
diff --git a/simpleperf/IOEventLoop_test.cpp b/simpleperf/IOEventLoop_test.cpp
index 3253502..cf231ba 100644
--- a/simpleperf/IOEventLoop_test.cpp
+++ b/simpleperf/IOEventLoop_test.cpp
@@ -215,3 +215,8 @@
close(fd[0]);
close(fd[1]);
}
+
+TEST(IOEventLoop, exit_before_loop) {
+ IOEventLoop loop;
+ ASSERT_TRUE(loop.ExitLoop());
+}
diff --git a/simpleperf/cmd_debug_unwind.cpp b/simpleperf/cmd_debug_unwind.cpp
index 10c5f37..edfad9f 100644
--- a/simpleperf/cmd_debug_unwind.cpp
+++ b/simpleperf/cmd_debug_unwind.cpp
@@ -169,11 +169,7 @@
return false;
}
} else if (args[i] == "--time") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseUint(args[i].c_str(), &selected_time_)) {
- LOG(ERROR) << "Invalid option for " << args[i-1] << ": " << args[i];
+ if (!GetUintOption(args, &i, &selected_time_)) {
return false;
}
} else {
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index c142feb..9e86965 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -28,7 +28,6 @@
#include <android-base/logging.h>
#include <android-base/file.h>
-#include <android-base/parsedouble.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <android-base/test_utils.h>
@@ -189,6 +188,8 @@
"-o record_file_name Set record file name, default is perf.data.\n"
"--exit-with-parent Stop recording when the process starting\n"
" simpleperf dies.\n"
+"--size-limit SIZE[K|M|G] Stop recording after SIZE bytes of records.\n"
+" Default is unlimited.\n"
"--start_profiling_fd fd_no After starting profiling, write \"STARTED\" to\n"
" <fd_no>, then close <fd_no>.\n"
"--symfs <dir> Look for files with symbols relative to this directory.\n"
@@ -300,6 +301,7 @@
bool in_app_context_;
bool trace_offcpu_;
bool exclude_kernel_callchain_;
+ uint64_t size_limit_in_bytes_ = 0;
// For CallChainJoiner
bool allow_callchain_joiner_;
@@ -565,13 +567,8 @@
} else if (args[i] == "-b") {
branch_sampling_ = branch_sampling_type_map["any"];
} else if (args[i] == "-c" || args[i] == "-f") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- char* endptr;
- uint64_t value = strtoull(args[i].c_str(), &endptr, 0);
- if (*endptr != '\0' || value == 0) {
- LOG(ERROR) << "Invalid option for " << args[i-1] << ": '" << args[i] << "'";
+ uint64_t value;
+ if (!GetUintOption(args, &i, &value, 1)) {
return false;
}
if (args[i-1] == "-c") {
@@ -596,11 +593,9 @@
fp_callchain_sampling_ = false;
dwarf_callchain_sampling_ = true;
if (strs.size() > 1) {
- char* endptr;
- uint64_t size = strtoull(strs[1].c_str(), &endptr, 0);
- if (*endptr != '\0' || size > UINT_MAX) {
- LOG(ERROR) << "invalid dump stack size in --call-graph option: "
- << strs[1];
+ uint64_t size;
+ if (!android::base::ParseUint(strs[1], &size)) {
+ LOG(ERROR) << "invalid dump stack size in --call-graph option: " << strs[1];
return false;
}
if ((size & 7) != 0) {
@@ -642,12 +637,7 @@
}
cpus_ = GetCpusFromString(args[i]);
} else if (args[i] == "--duration") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseDouble(args[i].c_str(), &duration_in_sec_,
- 1e-9)) {
- LOG(ERROR) << "Invalid duration: " << args[i].c_str();
+ if (!GetDoubleOption(args, &i, &duration_in_sec_, 1e-9)) {
return false;
}
} else if (args[i] == "-e") {
@@ -702,12 +692,11 @@
branch_sampling_ |= it->second;
}
} else if (args[i] == "-m") {
- if (!NextArgumentOrError(args, &i)) {
+ uint64_t pages;
+ if (!GetUintOption(args, &i, &pages)) {
return false;
}
- char* endptr;
- uint64_t pages = strtoull(args[i].c_str(), &endptr, 0);
- if (*endptr != '\0' || !IsPowerOfTwo(pages)) {
+ if (!IsPowerOfTwo(pages)) {
LOG(ERROR) << "Invalid mmap_pages: '" << args[i] << "'";
return false;
}
@@ -723,12 +712,7 @@
} else if (args[i] == "--no-callchain-joiner") {
allow_callchain_joiner_ = false;
} else if (args[i] == "--callchain-joiner-min-matching-nodes") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseUint(args[i].c_str(), &callchain_joiner_min_matching_nodes_) ||
- callchain_joiner_min_matching_nodes_ < 1u) {
- LOG(ERROR) << "unexpected argument for " << args[i - 1] << " option";
+ if (!GetUintOption(args, &i, &callchain_joiner_min_matching_nodes_, 1)) {
return false;
}
} else if (args[i] == "-o") {
@@ -754,12 +738,13 @@
LOG(ERROR) << "unexpected option " << args[i];
return false;
}
- } else if (args[i] == "--start_profiling_fd") {
- if (!NextArgumentOrError(args, &i)) {
+ } else if (args[i] == "--size-limit") {
+ if (!GetUintOption(args, &i, &size_limit_in_bytes_, 1, std::numeric_limits<uint64_t>::max(),
+ true)) {
return false;
}
- if (!android::base::ParseInt(args[i].c_str(), &start_profiling_fd_, 0)) {
- LOG(ERROR) << "Invalid start_profiling_fd: " << args[i];
+ } else if (args[i] == "--start_profiling_fd") {
+ if (!GetUintOption(args, &i, &start_profiling_fd_)) {
return false;
}
} else if (args[i] == "--symfs") {
@@ -1051,6 +1036,11 @@
if (ShouldOmitRecord(record)) {
return true;
}
+ if (size_limit_in_bytes_ > 0u) {
+ if (size_limit_in_bytes_ < record_file_writer_->GetDataSectionSize()) {
+ return event_selection_set_.GetIOEventLoop()->ExitLoop();
+ }
+ }
last_record_timestamp_ = record->Timestamp();
if (unwind_dwarf_callchain_) {
if (post_unwind_) {
diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp
index a01c6bc..cab1a38 100644
--- a/simpleperf/cmd_record_test.cpp
+++ b/simpleperf/cmd_record_test.cpp
@@ -570,3 +570,17 @@
TemporaryFile tmpfile;
ASSERT_TRUE(RecordCmd()->Run({"-o", tmpfile.path, "--", "sleep", "1"}));
}
+
+TEST(record_cmd, size_limit_option) {
+ std::vector<std::unique_ptr<Workload>> workloads;
+ CreateProcesses(1, &workloads);
+ std::string pid = std::to_string(workloads[0]->GetPid());
+ TemporaryFile tmpfile;
+ ASSERT_TRUE(RecordCmd()->Run({"-o", tmpfile.path, "-p", pid, "--size-limit", "1k", "--duration",
+ "1"}));
+ std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path);
+ ASSERT_TRUE(reader);
+ ASSERT_GT(reader->FileHeader().data.size, 1000u);
+ ASSERT_LT(reader->FileHeader().data.size, 2000u);
+ ASSERT_FALSE(RunRecordCmd({"--size-limit", "0"}));
+}
diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp
index 6a757f0..1a4cb4c 100644
--- a/simpleperf/cmd_report.cpp
+++ b/simpleperf/cmd_report.cpp
@@ -26,7 +26,6 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/parsedouble.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
@@ -561,11 +560,7 @@
}
Dso::SetKallsyms(kallsyms);
} else if (args[i] == "--max-stack") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseUint(args[i].c_str(), &callgraph_max_stack_)) {
- LOG(ERROR) << "invalid arg for --max-stack: " << args[i];
+ if (!GetUintOption(args, &i, &callgraph_max_stack_)) {
return false;
}
} else if (args[i] == "-n") {
@@ -581,13 +576,9 @@
}
report_filename_ = args[i];
} else if (args[i] == "--percent-limit") {
- if (!NextArgumentOrError(args, &i)) {
+ if (!GetDoubleOption(args, &i, &callgraph_percent_limit_)) {
return false;
}
- if (!android::base::ParseDouble(args[i].c_str(),
- &callgraph_percent_limit_, 0.0)) {
- LOG(ERROR) << "invalid arg for --percent-limit: " << args[i];
- }
} else if (args[i] == "--pids" || args[i] == "--tids") {
const std::string& option = args[i];
std::unordered_set<int>& filter =
diff --git a/simpleperf/cmd_report_sample.cpp b/simpleperf/cmd_report_sample.cpp
index 19fdaa5..897f5ef 100644
--- a/simpleperf/cmd_report_sample.cpp
+++ b/simpleperf/cmd_report_sample.cpp
@@ -365,6 +365,9 @@
for (int i = 0; i < file.symbol_size(); ++i) {
FprintIndented(report_fp_, 1, "symbol: %s\n", file.symbol(i).c_str());
}
+ for (int i = 0; i < file.mangled_symbol_size(); ++i) {
+ FprintIndented(report_fp_, 1, "mangled_symbol: %s\n", file.mangled_symbol(i).c_str());
+ }
if (file.id() != files.size()) {
LOG(ERROR) << "file id doesn't increase orderly, expected "
<< files.size() << ", really " << file.id();
@@ -627,6 +630,8 @@
for (const auto& sym : dump_symbols) {
std::string* symbol = file->add_symbol();
*symbol = sym->DemangledName();
+ std::string* mangled_symbol = file->add_mangled_symbol();
+ *mangled_symbol = sym->Name();
}
if (!WriteRecordInProtobuf(proto_record)) {
return false;
diff --git a/simpleperf/cmd_report_sample_test.cpp b/simpleperf/cmd_report_sample_test.cpp
index 87e559a..f298cfb 100644
--- a/simpleperf/cmd_report_sample_test.cpp
+++ b/simpleperf/cmd_report_sample_test.cpp
@@ -143,3 +143,12 @@
{"--show-callchain", "--show-art-frames"});
ASSERT_NE(data.find("artMterpAsmInstructionStart"), std::string::npos);
}
+
+TEST(cmd_report_sample, show_symbols_before_and_after_demangle) {
+ std::string data;
+ GetProtobufReport(PERF_DATA_WITH_INTERPRETER_FRAMES, &data, {"--show-callchain"});
+ ASSERT_NE(data.find("symbol: android::hardware::IPCThreadState::talkWithDriver(bool)"),
+ std::string::npos);
+ ASSERT_NE(data.find("mangled_symbol: _ZN7android8hardware14IPCThreadState14talkWithDriverEb"),
+ std::string::npos);
+}
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 21c74ea..da5b603 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -28,7 +28,6 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/parsedouble.h>
#include <android-base/strings.h>
#include "command.h"
@@ -531,21 +530,11 @@
} else if (args[i] == "--csv") {
csv_ = true;
} else if (args[i] == "--duration") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseDouble(args[i].c_str(), &duration_in_sec_,
- 1e-9)) {
- LOG(ERROR) << "Invalid duration: " << args[i].c_str();
+ if (!GetDoubleOption(args, &i, &duration_in_sec_, 1e-9)) {
return false;
}
} else if (args[i] == "--interval") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseDouble(args[i].c_str(), &interval_in_ms_,
- 1e-9)) {
- LOG(ERROR) << "Invalid interval: " << args[i].c_str();
+ if (!GetDoubleOption(args, &i, &interval_in_ms_, 1e-9)) {
return false;
}
} else if (args[i] == "--interval-only-values") {
diff --git a/simpleperf/cmd_trace_sched.cpp b/simpleperf/cmd_trace_sched.cpp
index afef072..6d61d9e 100644
--- a/simpleperf/cmd_trace_sched.cpp
+++ b/simpleperf/cmd_trace_sched.cpp
@@ -21,7 +21,6 @@
#include <vector>
#include <android-base/logging.h>
-#include <android-base/parsedouble.h>
#include <android-base/stringprintf.h>
#include <android-base/test_utils.h>
@@ -140,27 +139,15 @@
size_t i;
for (i = 0; i < args.size(); ++i) {
if (args[i] == "--duration") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseDouble(args[i].c_str(), &duration_in_sec_, 1e-9)) {
- LOG(ERROR) << "Invalid duration for " << args[i-1];
+ if (!GetDoubleOption(args, &i, &duration_in_sec_, 1e-9)) {
return false;
}
} else if (args[i] == "--check-spinloop") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseDouble(args[i].c_str(), &spinloop_check_period_in_sec_, 1e-9)) {
- LOG(ERROR) << "Invalid check period for " << args[i-1];
+ if (!GetDoubleOption(args, &i, &spinloop_check_period_in_sec_, 1e-9)) {
return false;
}
} else if (args[i] == "--spin-rate") {
- if (!NextArgumentOrError(args, &i)) {
- return false;
- }
- if (!android::base::ParseDouble(args[i].c_str(), &spinloop_check_rate_, 1e-9, 1.0)) {
- LOG(ERROR) << "Invalid spin rate for " << args[i-1];
+ if (!GetDoubleOption(args, &i, &spinloop_check_rate_, 1e-9, 1.0)) {
return false;
}
} else if (args[i] == "--show-threads") {
diff --git a/simpleperf/command.cpp b/simpleperf/command.cpp
index 63a7dfd..9caadaa 100644
--- a/simpleperf/command.cpp
+++ b/simpleperf/command.cpp
@@ -22,6 +22,8 @@
#include <vector>
#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
+#include <android-base/parseint.h>
#include <android-base/quick_exit.h>
#include "utils.h"
@@ -36,6 +38,18 @@
return true;
}
+bool Command::GetDoubleOption(const std::vector<std::string>& args, size_t* pi, double* value,
+ double min, double max) {
+ if (!NextArgumentOrError(args, pi)) {
+ return false;
+ }
+ if (!android::base::ParseDouble(args[*pi].c_str(), value, min, max)) {
+ LOG(ERROR) << "Invalid argument for option " << args[*pi - 1] << ": " << args[*pi];
+ return false;
+ }
+ return true;
+}
+
void Command::ReportUnknownOption(const std::vector<std::string>& args, size_t i) {
LOG(ERROR) << "Unknown option for " << name_ << " command: '" << args[i]
<< "'. Try `simpleperf help " << name_ << "`";
diff --git a/simpleperf/command.h b/simpleperf/command.h
index 6063dbf..2ce789e 100644
--- a/simpleperf/command.h
+++ b/simpleperf/command.h
@@ -19,10 +19,13 @@
#include <functional>
#include <memory>
+#include <limits>
#include <string>
#include <vector>
+#include <android-base/logging.h>
#include <android-base/macros.h>
+#include <android-base/parseint.h>
class Command {
public:
@@ -48,6 +51,24 @@
virtual bool Run(const std::vector<std::string>& args) = 0;
+ template <typename T>
+ bool GetUintOption(const std::vector<std::string>& args, size_t* pi, T* value, uint64_t min = 0,
+ uint64_t max = std::numeric_limits<T>::max(), bool allow_suffixes = false) {
+ if (!NextArgumentOrError(args, pi)) {
+ return false;
+ }
+ uint64_t tmp_value;
+ if (!android::base::ParseUint(args[*pi], &tmp_value, max, allow_suffixes) || tmp_value < min) {
+ LOG(ERROR) << "Invalid argument for option " << args[*pi - 1] << ": " << args[*pi];
+ return false;
+ }
+ *value = static_cast<T>(tmp_value);
+ return true;
+ }
+
+ bool GetDoubleOption(const std::vector<std::string>& args, size_t* pi, double* value,
+ double min = 0, double max = std::numeric_limits<double>::max());
+
protected:
bool NextArgumentOrError(const std::vector<std::string>& args, size_t* pi);
void ReportUnknownOption(const std::vector<std::string>& args, size_t i);
diff --git a/simpleperf/command_test.cpp b/simpleperf/command_test.cpp
index 18cb569..29c745e 100644
--- a/simpleperf/command_test.cpp
+++ b/simpleperf/command_test.cpp
@@ -43,3 +43,30 @@
UnRegisterCommand("mock1");
ASSERT_EQ(command_count, GetAllCommandNames().size());
}
+
+TEST(command, GetValueForOption) {
+ MockCommand command;
+ uint64_t value;
+ size_t i;
+ for (bool allow_suffixes : {true, false}) {
+ i = 0;
+ ASSERT_TRUE(command.GetUintOption({"-s", "156"}, &i, &value, 0,
+ std::numeric_limits<uint64_t>::max(), allow_suffixes));
+ ASSERT_EQ(i, 1u);
+ ASSERT_EQ(value, 156u);
+ }
+ i = 0;
+ ASSERT_TRUE(command.GetUintOption({"-s", "156k"}, &i, &value, 0,
+ std::numeric_limits<uint64_t>::max(), true));
+ ASSERT_EQ(value, 156 * (1ULL << 10));
+ i = 0;
+ ASSERT_FALSE(command.GetUintOption({"-s"}, &i, &value));
+ i = 0;
+ ASSERT_FALSE(command.GetUintOption({"-s", "0"}, &i, &value, 1));
+ i = 0;
+ ASSERT_FALSE(command.GetUintOption({"-s", "156"}, &i, &value, 0, 155));
+ i = 0;
+ double double_value;
+ ASSERT_TRUE(command.GetDoubleOption({"-s", "3.2"}, &i, &double_value, 0, 4));
+ ASSERT_DOUBLE_EQ(double_value, 3.2);
+}
diff --git a/simpleperf/record_file.h b/simpleperf/record_file.h
index c90b269..4ec6c31 100644
--- a/simpleperf/record_file.h
+++ b/simpleperf/record_file.h
@@ -47,6 +47,7 @@
bool WriteAttrSection(const std::vector<EventAttrWithId>& attr_ids);
bool WriteRecord(const Record& record);
+ uint64_t GetDataSectionSize() const { return data_section_size_; }
bool ReadDataSection(const std::function<void(const Record*)>& callback);
bool BeginWriteFeatures(size_t feature_count);
diff --git a/simpleperf/report_sample.proto b/simpleperf/report_sample.proto
index 1a4886e..bbe46fb 100644
--- a/simpleperf/report_sample.proto
+++ b/simpleperf/report_sample.proto
@@ -69,6 +69,9 @@
// symbol table of the file.
repeated string symbol = 3;
+
+ // mangled symbol table of the file.
+ repeated string mangled_symbol = 4;
}
message Thread {
diff --git a/simpleperf/scripts/run_simpleperf_without_usb_connection.py b/simpleperf/scripts/run_simpleperf_without_usb_connection.py
index b26b7b9..a3524f6 100644
--- a/simpleperf/scripts/run_simpleperf_without_usb_connection.py
+++ b/simpleperf/scripts/run_simpleperf_without_usb_connection.py
@@ -45,6 +45,8 @@
shell_cmd = 'cd /data/local/tmp && nohup ./simpleperf record ' + args.record_options
if args.app:
shell_cmd += ' --app ' + args.app
+ if args.size_limit:
+ shell_cmd += ' --size-limit ' + args.size_limit
shell_cmd += ' >/data/local/tmp/simpleperf_output 2>&1'
print('shell_cmd: %s' % shell_cmd)
subproc = subprocess.Popen([adb.adb_path, 'shell', shell_cmd])
@@ -67,8 +69,8 @@
print('Waiting for simpleperf process to finish...')
while adb.run(['shell', 'pidof', 'simpleperf']):
time.sleep(1)
- adb.check_run(['pull', '/data/local/tmp/perf.data', args.perf_data_path])
adb.run(['shell', 'cat', '/data/local/tmp/simpleperf_output'])
+ adb.check_run(['pull', '/data/local/tmp/perf.data', args.perf_data_path])
print('The recording data has been collected in %s.' % args.perf_data_path)
def main():
@@ -79,9 +81,12 @@
start_parser.add_argument('-r', '--record_options',
default='-e task-clock:u -g',
help="""Set options for `simpleperf record` command.
- Default is '-e task-clock:u -g'.""")
+ Default is `-e task-clock:u -g`.""")
start_parser.add_argument('-p', '--app', help="""Profile an Android app, given the package
- name. Like -p com.example.android.myapp.""")
+ name. Like `-p com.example.android.myapp`.""")
+ start_parser.add_argument('--size_limit', type=str,
+ help="""Stop profiling when recording data reaches
+ [size_limit][K|M|G] bytes. Like `--size_limit 1M`.""")
start_parser.set_defaults(func=start_recording)
stop_parser = subparsers.add_parser('stop', help='Stop recording.')
stop_parser.add_argument('-o', '--perf_data_path', default='perf.data', help="""The path to
diff --git a/simpleperf/scripts/test.py b/simpleperf/scripts/test.py
index 64bc4a4..b8aeeb6 100644
--- a/simpleperf/scripts/test.py
+++ b/simpleperf/scripts/test.py
@@ -451,7 +451,7 @@
def test_run_simpleperf_without_usb_connection(self):
self.adb.check_run(['shell', 'am', 'start', '-n', self.package_name + '/.MainActivity'])
self.run_cmd(['run_simpleperf_without_usb_connection.py', 'start', '-p',
- self.package_name])
+ self.package_name, '--size_limit', '1M'])
self.adb.check_run(['kill-server'])
time.sleep(3)
self.run_cmd(['run_simpleperf_without_usb_connection.py', 'stop'])