Skip to content

Commit 8de35b8

Browse files
committed
Fix tabs, newlines, and spaces getting in the structured data
1 parent a33b865 commit 8de35b8

File tree

2 files changed

+81
-14
lines changed

2 files changed

+81
-14
lines changed

lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "NativeThreadLinux.h"
2424
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
2525
#include "Plugins/Process/Utility/LinuxProcMaps.h"
26+
#include "Plugins/Process/Utility/LinuxProcStatus.h"
2627
#include "Procfs.h"
2728
#include "lldb/Core/ModuleSpec.h"
2829
#include "lldb/Host/Host.h"
@@ -443,10 +444,29 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
443444
SetCurrentThreadID(tids[0]);
444445
SetState(StateType::eStateStopped, false);
445446
}
447+
static bool IsCoredumping(lldb::pid_t pid) {
448+
auto BufferOrError = getProcFile(pid, "status");
449+
if (!BufferOrError)
450+
return false;
451+
452+
lldb_private::StructuredData::Dictionary proc_status =
453+
ParseProcStatus(BufferOrError.get()->getBuffer());
454+
455+
if (!proc_status.HasKey("CoreDumping"))
456+
return false;
457+
458+
llvm::StringRef result;
459+
if (!proc_status.GetValueForKeyAsString("CoreDumping", result))
460+
return false;
461+
462+
return result == "1";
463+
}
446464

447465
llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
448466
Log *log = GetLog(POSIXLog::Process);
449467

468+
bool coreDumping = IsCoredumping(pid);
469+
LLDB_LOG(log, "{0} coredumping: {1}", pid, coreDumping);
450470
Status status;
451471
// Use a map to keep track of the threads which we have attached/need to
452472
// attach.
@@ -457,21 +477,55 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
457477
if (it->second == false) {
458478
lldb::tid_t tid = it->first;
459479

460-
// Attach to the requested process.
461-
// An attach will cause the thread to stop with a SIGSTOP.
462-
if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
463-
// No such thread. The thread may have exited. More error handling
464-
// may be needed.
465-
if (status.GetError() == ESRCH) {
466-
it = tids_to_attach.erase(it);
467-
continue;
480+
if (!coreDumping) {
481+
// Attach to the requested process.
482+
// An attach will cause the thread to stop with a SIGSTOP.
483+
if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
484+
// No such thread. The thread may have exited. More error handling
485+
// may be needed.
486+
if (status.GetError() == ESRCH) {
487+
it = tids_to_attach.erase(it);
488+
continue;
489+
}
490+
if (status.GetError() == EPERM) {
491+
// Depending on the value of ptrace_scope, we can return a
492+
// different error that suggests how to fix it.
493+
return AddPtraceScopeNote(status.ToError());
494+
}
495+
return status.ToError();
468496
}
469-
if (status.GetError() == EPERM) {
470-
// Depending on the value of ptrace_scope, we can return a different
471-
// error that suggests how to fix it.
472-
return AddPtraceScopeNote(status.ToError());
497+
} else {
498+
long options = PTRACE_O_TRACEEXIT | PTRACE_O_TRACESYSGOOD;
499+
if ((status =
500+
PtraceWrapper(PTRACE_SEIZE, tid, nullptr, (void *)options))
501+
.Fail()) {
502+
// No such thread. The thread may have exited. More error handling
503+
// may be needed.
504+
if (status.GetError() == ESRCH) {
505+
it = tids_to_attach.erase(it);
506+
continue;
507+
}
508+
if (status.GetError() == EPERM) {
509+
// Depending on the value of ptrace_scope, we can return a
510+
// different error that suggests how to fix it.
511+
return AddPtraceScopeNote(status.ToError());
512+
}
513+
return status.ToError();
514+
}
515+
if ((status = PtraceWrapper(PTRACE_INTERRUPT, tid)).Fail()) {
516+
// No such thread. The thread may have exited. More error handling
517+
// may be needed.
518+
if (status.GetError() == ESRCH) {
519+
it = tids_to_attach.erase(it);
520+
continue;
521+
}
522+
if (status.GetError() == EPERM) {
523+
// Depending on the value of ptrace_scope, we can return a
524+
// different error that suggests how to fix it.
525+
return AddPtraceScopeNote(status.ToError());
526+
}
527+
return status.ToError();
473528
}
474-
return status.ToError();
475529
}
476530

477531
int wpid =

lldb/source/Plugins/Process/Utility/LinuxProcStatus.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <vector>
1313

1414
static std::vector<std::string> SplitLines(llvm::StringRef proc_status) {
15+
// Push everything to an input stream and then read it to a vec
16+
// line by line
1517
std::istringstream inputstream(proc_status.str());
1618
std::vector<std::string> lines;
1719
std::string line;
@@ -22,9 +24,12 @@ static std::vector<std::string> SplitLines(llvm::StringRef proc_status) {
2224
}
2325

2426
lldb_private::StructuredData::Dictionary
25-
ParseProcStatus(llvm::StringRef proc_status) {
27+
lldb_private::ParseProcStatus(llvm::StringRef proc_status) {
2628
std::vector<std::string> lines = SplitLines(proc_status);
2729
lldb_private::StructuredData::Dictionary proc_status_data;
30+
volatile bool debug = true;
31+
while (debug) {
32+
}
2833
for (auto &str : lines) {
2934
// proc/pid/status is a delineated by a colon, so we split all the lines
3035
// and then return a structureddata of each name : value. We keep these
@@ -35,6 +40,14 @@ ParseProcStatus(llvm::StringRef proc_status) {
3540
}
3641
std::string name = str.substr(0, colonPos);
3742
std::string value = str.substr(colonPos + 1);
43+
// All the leading values have a tab character, but
44+
// that's not explicitly documented on the man page so
45+
// we have this check to strip the tab, and any newline or
46+
// space characters
47+
value.erase(std::remove_if(
48+
value.begin(), value.end(),
49+
[](char c) { return c == '\t' || c == '\n' || c == ' '; }),
50+
value.end());
3851
proc_status_data.AddStringItem(name, value);
3952
}
4053

0 commit comments

Comments
 (0)