/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using ::android::meminfo::Format; using ::android::meminfo::GetFormat; [[noreturn]] static void usage(int exit_status) { std::cerr << "showmap [-aqtv] [-f FILE] PID\n" << "-a\taddresses (show virtual memory map)\n" << "-q\tquiet (don't show error if map could not be read)\n" << "-t\tterse (show only items with private pages)\n" << "-v\tverbose (don't coalesce maps with the same name)\n" << "-f\tFILE (read from input from FILE instead of PID)\n" << "-o\t[raw][json][csv] Print output in the specified format.\n" << " \tDefault output format is raw text. All memory in KB.)\n"; exit(exit_status); } int main(int argc, char* argv[]) { signal(SIGPIPE, SIG_IGN); struct option longopts[] = { {"help", no_argument, nullptr, 'h'}, {0, 0, nullptr, 0}, }; // Printing options. bool terse = false; bool quiet = false; // Output options. bool show_addr = false; bool verbose = false; Format format = Format::RAW; // 'pid' will be ignored if a file is specified. std::string filename; pid_t pid = 0; int opt; while ((opt = getopt_long(argc, argv, "tvaqf:o:h", longopts, nullptr)) != -1) { switch (opt) { case 't': terse = true; break; case 'a': show_addr = true; break; case 'v': verbose = true; break; case 'q': quiet = true; break; case 'f': filename = optarg; break; case 'o': format = GetFormat(optarg); if (format == Format::INVALID) { std::cerr << "Invalid format.\n"; usage(EXIT_FAILURE); } break; case 'h': usage(EXIT_SUCCESS); default: usage(EXIT_FAILURE); } } if (filename.empty()) { if ((argc - 1) < optind) { std::cerr << "Invalid arguments: Must provide at the end\n"; usage(EXIT_FAILURE); } pid = atoi(argv[optind]); if (pid <= 0) { std::cerr << "Invalid process id " << argv[optind] << "\n"; usage(EXIT_FAILURE); } // run_showmap will read directly from this file and ignore the pid argument. filename = ::android::base::StringPrintf("/proc/%d/smaps", pid); } bool success = ::android::smapinfo::run_showmap(pid, filename, terse, verbose, show_addr, quiet, format, nullptr, std::cout, std::cerr); if (!success) { exit(EXIT_FAILURE); } return 0; }