summaryrefslogtreecommitdiff
path: root/Userland/Utilities
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-02-04 23:04:58 +0100
committerAndreas Kling <kling@serenityos.org>2021-02-04 23:20:39 +0100
commitb7d16e3496bc7fde24b2fb4590053b4cd4b1cd5c (patch)
tree86febb8618f483a622d5e068ce6926b58ec6fbbc /Userland/Utilities
parenta5d89ca5dfa39312862928b542819f05fc40df91 (diff)
downloadserenity-b7d16e3496bc7fde24b2fb4590053b4cd4b1cd5c.zip
LibSymbolClient+bt: Move bt logic to SymbolClient::symbolicate_thread()
Since this is useful in many places, let's have a common implementation of walking the stack of a given thread via /proc and symbolicating each of the frames.
Diffstat (limited to 'Userland/Utilities')
-rw-r--r--Userland/Utilities/bt.cpp115
1 files changed, 4 insertions, 111 deletions
diff --git a/Userland/Utilities/bt.cpp b/Userland/Utilities/bt.cpp
index 55fbbd6921..0bf569a0ad 100644
--- a/Userland/Utilities/bt.cpp
+++ b/Userland/Utilities/bt.cpp
@@ -24,9 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <AK/JsonArray.h>
-#include <AK/JsonObject.h>
-#include <AK/JsonValue.h>
#include <AK/LogStream.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/EventLoop.h>
@@ -63,118 +60,14 @@ int main(int argc, char** argv)
Core::ArgsParser args_parser;
pid_t pid = 0;
args_parser.add_positional_argument(pid, "PID", "pid");
-
args_parser.parse(argc, argv);
- struct RegionWithSymbols {
- FlatPtr base { 0 };
- size_t size { 0 };
- String path;
- bool is_relative { true };
- };
-
- Vector<FlatPtr> stack;
- Vector<RegionWithSymbols> regions;
-
- regions.append(RegionWithSymbols {
- .base = 0xc0000000,
- .size = 0x3fffffff,
- .path = "/boot/Kernel",
- .is_relative = false });
-
- {
- // FIXME: Support multiple threads in the same process!
- auto stack_path = String::formatted("/proc/{}/stacks/{}", pid, pid);
- auto file_or_error = Core::File::open(stack_path, Core::IODevice::ReadOnly);
- if (file_or_error.is_error()) {
- warnln("Could not open {}: {}", stack_path, file_or_error.error());
- return 1;
- }
-
- auto json = JsonValue::from_string(file_or_error.value()->read_all());
- if (!json.has_value() || !json.value().is_array()) {
- warnln("Invalid contents in {}", stack_path);
- return 1;
- }
-
- stack.ensure_capacity(json.value().as_array().size());
- for (auto& value : json.value().as_array().values()) {
- stack.append(value.to_u32());
- }
- }
-
- {
- auto vm_path = String::formatted("/proc/{}/vm", pid);
- auto file_or_error = Core::File::open(vm_path, Core::IODevice::ReadOnly);
- if (file_or_error.is_error()) {
- warnln("Could not open {}: {}", vm_path, file_or_error.error());
- return 1;
- }
-
- auto json = JsonValue::from_string(file_or_error.value()->read_all());
- if (!json.has_value() || !json.value().is_array()) {
- warnln("Invalid contents in {}", vm_path);
- return 1;
- }
-
- for (auto& region_value : json.value().as_array().values()) {
- auto& region = region_value.as_object();
- auto name = region.get("name").to_string();
- auto address = region.get("address").to_u32();
- auto size = region.get("size").to_u32();
-
- String path;
- if (name == "/usr/lib/Loader.so") {
- path = name;
- } else if (name.ends_with(": .text")) {
- auto parts = name.split_view(':');
- path = parts[0];
- if (!path.starts_with('/'))
- path = String::formatted("/usr/lib/{}", path);
- } else {
- continue;
- }
-
- RegionWithSymbols r;
- r.base = address;
- r.size = size;
- r.path = path;
- regions.append(move(r));
- }
- }
-
Core::EventLoop loop;
- auto client = SymbolClient::Client::construct();
-
- for (auto address : stack) {
- const RegionWithSymbols* found_region = nullptr;
- for (auto& region : regions) {
- if (address >= region.base && address < (region.base + region.size)) {
- found_region = &region;
- break;
- }
- }
-
- if (!found_region) {
- outln("{:p} ??", address);
- continue;
- }
-
- Vector<FlatPtr> addresses;
- if (found_region->is_relative)
- addresses.append(address - found_region->base);
- else
- addresses.append(address);
-
- auto symbols = client->symbolicate(found_region->path, addresses);
- if (symbols.is_empty()) {
- outln("{:p} ??", address);
- continue;
- }
-
- outln("{:p} {}", address, symbols[0].name);
+ // FIXME: Support multiple threads in the same process!
+ auto symbols = SymbolClient::symbolicate_thread(pid, pid);
+ for (auto& symbol : symbols) {
+ outln("{:p} {}", symbol.address, symbol.name);
}
-
return 0;
}