labath created this revision. labath added reviewers: jingham, clayborg. Herald added a project: LLDB. labath added a comment.
Note: I am certain that there will be things which will fail for these kinds of "processes" -- there's plenty of `!= LLDB_INVALID_PID` checks, but most of them seem to be on the launch/attach code paths which are not exercised here. I am fine with fixing these as they are discovered -- the bigger question here is whether this is a reasonable direction to take lldb in. I think it is, because most of the `!= LLDB_INVALID_PID` checks look like they could be replaced by a check of the process state. Normally, on linux we retrieve the process ID from the LinuxProcStatus stream (which is just the contents of /proc/%d/status pseudo-file). However, this stream is not strictly required (it's a breakpad extension), and we are encountering a fair amount of minidumps which do not have it present. It's not clear whether this is the case with all these minidumps, but the two known situations where this stream can be missing are: - /proc filesystem not mounted (or something to that effect) - process crashing after exhausting (almost) all file descriptors (so the minidump writer may not be able to open the /proc file) At first I wanted to do something similar to what the gdb-remote plugin does when talking to bare metal gdb stubs and like, and "invent" a process ID in this case. However, then I noticed that most of the things "just work" even if I leave the proces ID as "invalid". Since it seems we have multiple use cases for a "process" without a "process id", what I do in this patch instead is "downgrade" the missing pid case to a warning. I also changes the "process status" output to better handle the case of a missing/unknown pid. The test case in this patch verifies that basic functionality still works even with a pid-less minidump. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D70238 Files: lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp lldb/source/Target/Process.cpp lldb/test/Shell/Minidump/no-process-id.yaml
Index: lldb/test/Shell/Minidump/no-process-id.yaml =================================================================== --- /dev/null +++ lldb/test/Shell/Minidump/no-process-id.yaml @@ -0,0 +1,38 @@ +# RUN: yaml2obj %s > %t +# RUN: %lldb -c %t -o "thread list" -o "register read" -b 2>&1 | FileCheck %s + +# CHECK: (lldb) target create --core +# CHECK: Unable to retrieve process ID from minidump file. +# CHECK: Core file {{.*}} was loaded. + +# CHECK: (lldb) thread list +# CHECK: Process stopped +# CHECK: * thread #1: tid = 16001, 0x0000000000401dc6 a.out + +# CHECK: (lldb) register read +# CHECK: rsp = 0x00007ffceb34a210 + +--- !minidump +Streams: + - Type: ThreadList + Threads: + - Thread Id: 0x00003E81 + Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Stack: + Start of Memory Range: 0x00007FFCEB34A000 + Content: '' + - Type: ModuleList + Modules: + - Base of Image: 0x0000000000400000 + Size of Image: 0x00017000 + Module Name: 'a.out' + CodeView Record: '' + - Type: SystemInfo + Processor Arch: AMD64 + Platform ID: Linux + CSD Version: 'Linux 3.13' + CPU: + Vendor ID: GenuineIntel + Version Info: 0x00000000 + Feature Info: 0x00000000 +... Index: lldb/source/Target/Process.cpp =================================================================== --- lldb/source/Target/Process.cpp +++ lldb/source/Target/Process.cpp @@ -5428,23 +5428,30 @@ } void Process::GetStatus(Stream &strm) { + llvm::raw_ostream &OS = strm.AsRawOstream(); const StateType state = GetState(); + if (state == eStateConnected) { + OS << "Connected to remote target.\n"; + return; + } + + OS << "Process "; + if (GetID() != LLDB_INVALID_PROCESS_ID) + OS << GetID() << ' '; + if (StateIsStoppedState(state, false)) { if (state == eStateExited) { int exit_status = GetExitStatus(); const char *exit_description = GetExitDescription(); - strm.Printf("Process %" PRIu64 " exited with status = %i (0x%8.8x) %s\n", - GetID(), exit_status, exit_status, - exit_description ? exit_description : ""); + OS << llvm::format("exited with status = %i (0x%8.8x) %s", exit_status, + exit_status, exit_description ? exit_description : ""); } else { - if (state == eStateConnected) - strm.Printf("Connected to remote target.\n"); - else - strm.Printf("Process %" PRIu64 " %s\n", GetID(), StateAsCString(state)); + OS << llvm::formatv("{0}", state); } } else { - strm.Printf("Process %" PRIu64 " is running.\n", GetID()); + OS << "is running."; } + OS << "\n"; } size_t Process::GetThreadStatus(Stream &strm, Index: lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp =================================================================== --- lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -226,10 +226,10 @@ llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid(); if (!pid) { - error.SetErrorString("failed to parse PID"); - return error; - } - SetID(pid.getValue()); + GetTarget().GetDebugger().GetAsyncErrorStream()->PutCString( + "Unable to retrieve process ID from minidump file.\n"); + } else + SetID(pid.getValue()); return error; }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits