#include "config.h"
#include "configreader.h"
+#include "map_utils.h"
#include "perfprofdcore.h"
+#include "perfprofd_cmdline.h"
#include "quipper_helper.h"
#include "symbolizer.h"
using namespace android::perfprofd::quipper;
+static_assert(android::base::kEnableDChecks, "Expected DCHECKs to be enabled");
+
//
// Set to argv[0] on startup
//
}
private:
- void TestLogFunction(LogId log_id ATTRIBUTE_UNUSED,
+ void TestLogFunction(LogId log_id,
LogSeverity severity,
const char* tag,
- const char* file ATTRIBUTE_UNUSED,
- unsigned int line ATTRIBUTE_UNUSED,
+ const char* file,
+ unsigned int line,
const char* message) {
std::unique_lock<std::mutex> ul(lock_);
constexpr char log_characters[] = "VDIWEFF";
char severity_char = log_characters[severity];
test_log_messages_.push_back(android::base::StringPrintf("%c: %s", severity_char, message));
+
+ if (severity >= LogSeverity::FATAL_WITHOUT_ABORT) {
+ android::base::StderrLogger(log_id, severity, tag, file, line, message);
+ }
}
private:
// assorted bad syntax
runner.addToConfig("collection_interval=0");
runner.addToConfig("collection_interval=-1");
- runner.addToConfig("collection_interval=2");
runner.addToConfig("nonexistent_key=something");
runner.addToConfig("no_equals_stmt");
// Verify log contents
const std::string expected = RAW_RESULT(
- W: line 6: specified value 0 for 'collection_interval' outside permitted range [100 4294967295] (ignored)
+ W: line 6: specified value 0 for 'collection_interval' outside permitted range [1 4294967295] (ignored)
W: line 7: malformed unsigned value (ignored)
- W: line 8: specified value 2 for 'collection_interval' outside permitted range [100 4294967295] (ignored)
- W: line 9: unknown option 'nonexistent_key' ignored
- W: line 10: line malformed (no '=' found)
+ W: line 8: unknown option 'nonexistent_key' ignored
+ W: line 9: line malformed (no '=' found)
);
// check to make sure log excerpt matches
VerifyBasicCannedProfile(encodedProfile);
}
-TEST_F(BasicRunWithCannedPerf, DISABLED_WithSymbolizer)
+TEST_F(BasicRunWithCannedPerf, WithSymbolizer)
{
//
// Verify the portion of the daemon that reads and encodes
std::string Decode(const std::string& dso, uint64_t address) override {
return dso + "@" + std::to_string(address);
}
+ bool GetMinExecutableVAddr(const std::string& dso, uint64_t* addr) override {
+ *addr = 4096;
+ return true;
+ }
};
TestSymbolizer test_symbolizer;
PROFILE_RESULT result =
VerifyBasicCannedProfile(encodedProfile);
- // TODO: Re-add symbolization.
+ auto find_symbol = [&](const std::string& filename)
+ -> const android::perfprofd::PerfprofdRecord_SymbolInfo* {
+ for (auto& symbol_info : encodedProfile.symbol_info()) {
+ if (symbol_info.filename() == filename) {
+ return &symbol_info;
+ }
+ }
+ return nullptr;
+ };
+ auto all_filenames = [&]() {
+ std::ostringstream oss;
+ for (auto& symbol_info : encodedProfile.symbol_info()) {
+ oss << " " << symbol_info.filename();
+ }
+ return oss.str();
+ };
+
+ EXPECT_TRUE(find_symbol("/data/app/com.google.android.apps.plus-1/lib/arm/libcronet.so")
+ != nullptr) << all_filenames() << test_logger.JoinTestLog("\n");
+ EXPECT_TRUE(find_symbol("/data/dalvik-cache/arm/system@framework@wifi-service.jar@classes.dex")
+ != nullptr) << all_filenames();
+ EXPECT_TRUE(find_symbol("/data/dalvik-cache/arm/data@app@com.google.android.gms-2@base.apk@"
+ "classes.dex")
+ != nullptr) << all_filenames();
+ EXPECT_TRUE(find_symbol("/data/dalvik-cache/arm/system@framework@boot.oat") != nullptr)
+ << all_filenames();
}
TEST_F(PerfProfdTest, CallchainRunWithCannedPerf)
#endif
+class RangeMapTest : public testing::Test {
+};
+
+TEST_F(RangeMapTest, TestRangeMap) {
+ using namespace android::perfprofd;
+
+ RangeMap<std::string, uint64_t> map;
+ auto print = [&]() {
+ std::ostringstream oss;
+ for (auto& aggr_sym : map) {
+ oss << aggr_sym.first << "#" << aggr_sym.second.symbol;
+ oss << "[";
+ for (auto& x : aggr_sym.second.offsets) {
+ oss << x << ",";
+ }
+ oss << "]";
+ }
+ return oss.str();
+ };
+
+ EXPECT_STREQ("", print().c_str());
+
+ map.Insert("a", 10);
+ EXPECT_STREQ("10#a[10,]", print().c_str());
+ map.Insert("a", 100);
+ EXPECT_STREQ("10#a[10,100,]", print().c_str());
+ map.Insert("a", 1);
+ EXPECT_STREQ("1#a[1,10,100,]", print().c_str());
+ map.Insert("a", 1);
+ EXPECT_STREQ("1#a[1,10,100,]", print().c_str());
+ map.Insert("a", 2);
+ EXPECT_STREQ("1#a[1,2,10,100,]", print().c_str());
+
+ map.Insert("b", 200);
+ EXPECT_STREQ("1#a[1,2,10,100,]200#b[200,]", print().c_str());
+ map.Insert("b", 199);
+ EXPECT_STREQ("1#a[1,2,10,100,]199#b[199,200,]", print().c_str());
+
+ map.Insert("c", 50);
+ EXPECT_STREQ("1#a[1,2,10,]50#c[50,]100#a[100,]199#b[199,200,]", print().c_str());
+}
+
int main(int argc, char **argv) {
// Always log to cerr, so that device failures are visible.
android::base::SetLogger(android::base::StderrLogger);