diff --git a/src/common.h b/src/common.h index eadf02372..ae9950ac6 100644 --- a/src/common.h +++ b/src/common.h @@ -495,14 +495,16 @@ inline wcstring to_string(long x) { return wcstring(buff); } -inline wcstring to_string(int x) { return to_string(static_cast(x)); } - -inline wcstring to_string(size_t x) { +inline wcstring to_string(unsigned long long x) { wchar_t buff[64]; format_ullong_safe(buff, x); return wcstring(buff); } +inline wcstring to_string(int x) { return to_string(static_cast(x)); } + +inline wcstring to_string(size_t x) { return to_string(static_cast(x)); } + inline bool bool_from_string(const std::string &x) { if (x.empty()) return false; switch (x.front()) { diff --git a/src/exec.cpp b/src/exec.cpp index c988ea52c..a43b24829 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -369,6 +369,9 @@ static bool run_internal_process(process_t *p, std::string outdata, std::string p->internal_proc_ = std::make_shared(); f->internal_proc = p->internal_proc_; + FLOGF(proc_internal_proc, "Created internal proc %llu to write output for proc '%ls'", + p->internal_proc_->get_id(), p->argv0()); + // Resolve the IO chain. // Note it's important we do this even if we have no out or err data, because we may have been // asked to truncate a file (e.g. `echo -n '' > /tmp/truncateme.txt'). The open() in the dup2 diff --git a/src/flog.h b/src/flog.h index 48b5728ba..3e7838d65 100644 --- a/src/flog.h +++ b/src/flog.h @@ -59,6 +59,8 @@ class category_list_t { category_t proc_termowner{L"proc-termowner", L"Terminal ownership events"}; + category_t proc_internal_proc{L"proc-internal-proc", L"Internal (non-forked) process events"}; + category_t env_locale{L"env-locale", L"Changes to locale variables"}; }; diff --git a/src/proc.cpp b/src/proc.cpp index a9615f93a..b41c3247f 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -214,8 +214,17 @@ void internal_proc_t::mark_exited(proc_status_t status) { status_.store(status, std::memory_order_relaxed); exited_.store(true, std::memory_order_release); topic_monitor_t::principal().post(topic_t::internal_exit); + FLOG(proc_internal_proc, "Internal proc", internal_proc_id_, "exited with status", + status.status_value()); } +static int64_t next_proc_id() { + static std::atomic s_next{}; + return ++s_next; +} + +internal_proc_t::internal_proc_t() : internal_proc_id_(next_proc_id()) {} + static void mark_job_complete(const job_t *j) { for (auto &p : j->processes) { p->completed = 1; diff --git a/src/proc.h b/src/proc.h index eb12e5b92..cc52fc845 100644 --- a/src/proc.h +++ b/src/proc.h @@ -113,6 +113,10 @@ class proc_status_t { /// A structure representing a "process" internal to fish. This is backed by a pthread instead of a /// separate process. class internal_proc_t { + /// An identifier for internal processes. + /// This is used for logging purposes only. + const uint64_t internal_proc_id_; + /// Whether the process has exited. std::atomic exited_{}; @@ -130,6 +134,10 @@ class internal_proc_t { assert(exited() && "Process is not exited"); return status_.load(std::memory_order_relaxed); } + + uint64_t get_id() const { return internal_proc_id_; } + + internal_proc_t(); }; /// A structure representing a single fish process. Contains variables for tracking process state