Compare commits
9 Commits
9f7877abac
...
961ebac983
Author | SHA1 | Date |
---|---|---|
Félix Baylac-Jacqué | 961ebac983 | |
Andreas Rammhold | 83a775313d | |
Andreas Rammhold | 0370c44d21 | |
Andreas Rammhold | 945b37227d | |
Eelco Dolstra | 3093bd3a85 | |
Eelco Dolstra | 285277a61a | |
Eelco Dolstra | ddd5503950 | |
Eelco Dolstra | 96eb5ef156 | |
Eelco Dolstra | 59a304a9a8 |
|
@ -0,0 +1,87 @@
|
|||
use std::io;
|
||||
use std::io::BufRead;
|
||||
|
||||
#[derive (PartialEq, Debug)]
|
||||
enum Direction {
|
||||
In,
|
||||
Out
|
||||
}
|
||||
|
||||
#[derive (PartialEq, Debug)]
|
||||
struct Event {
|
||||
ts: u64,
|
||||
line: u64,
|
||||
id: u64,
|
||||
probe_name: String,
|
||||
probe_direction: Direction,
|
||||
line_col: String,
|
||||
filename: String
|
||||
}
|
||||
|
||||
fn main () {
|
||||
let mut buf = String::new();
|
||||
let mut stdin_h = io::stdin().lock();
|
||||
let mut done = false;
|
||||
let mut stack: Vec<Event> = Vec::new();
|
||||
let mut line_nb: u64 = 1;
|
||||
while !done {
|
||||
match stdin_h.read_line(&mut buf) {
|
||||
Ok(0) => done = true,
|
||||
Ok(_) => process_line(&buf, &mut stack, &line_nb),
|
||||
Err(_err) => {
|
||||
panic!("Error while reading from stdin.");
|
||||
}
|
||||
}
|
||||
line_nb += 1;
|
||||
buf.clear();
|
||||
}
|
||||
eprintln!("NB lines: {}", line_nb);
|
||||
}
|
||||
|
||||
fn print_stack_names (stack: &Vec<Event>) -> String {
|
||||
let mut names_str = String::new();
|
||||
for event in stack {
|
||||
names_str.push_str(format!(";{}:{}:{}", &event.probe_name, &event.filename, &event.line_col).as_str());
|
||||
};
|
||||
names_str
|
||||
}
|
||||
|
||||
fn process_line(line: &str, stack: &mut Vec<Event>, line_nb: &u64) {
|
||||
let elems: Vec<&str> = line.split(' ').collect();
|
||||
let probe_elems: Vec<&str> = elems[2].split("__").collect();
|
||||
let probe_direction = match probe_elems[1] {
|
||||
"in" => Direction::In,
|
||||
"out" => Direction::Out,
|
||||
x => panic!("Unknown probe direction {}", x)
|
||||
};
|
||||
let mut filename = String::from(elems[4]);
|
||||
filename.truncate(filename.len() - 1);
|
||||
let event = Event {
|
||||
ts: elems[0].parse().expect(format!("Cannot parse timestamp for line {}", line_nb).as_str()),
|
||||
id: elems[1].parse().expect(format!("Cannot parse probe direction for line {}", line_nb).as_str()),
|
||||
line: line_nb.clone(),
|
||||
probe_name: String::from(probe_elems[0]),
|
||||
probe_direction,
|
||||
line_col: String::from(elems[3]),
|
||||
filename
|
||||
};
|
||||
|
||||
if event.probe_direction == Direction::In {
|
||||
stack.push(event);
|
||||
} else {
|
||||
let in_event = stack.pop().expect("Error: cannot pop stack, we lack a in event.");
|
||||
if !same_frame(&event, &in_event) {
|
||||
eprintln!("Weird trace!! We found a unmatched out event for");
|
||||
eprintln!("{:?}", in_event);
|
||||
eprintln!("{:?}", event);
|
||||
stack.push(in_event);
|
||||
panic!();
|
||||
}
|
||||
let dur = event.ts - in_event.ts;
|
||||
println!("{} {}", print_stack_names(&stack), dur);
|
||||
}
|
||||
}
|
||||
|
||||
fn same_frame(a: &Event, b: &Event) -> bool {
|
||||
a.id == b.id
|
||||
}
|
|
@ -104,6 +104,8 @@
|
|||
buildPackages.git
|
||||
buildPackages.mercurial # FIXME: remove? only needed for tests
|
||||
buildPackages.jq # Also for custom mdBook preprocessor.
|
||||
buildPackages.bear
|
||||
buildPackages.clang-tools
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [(buildPackages.util-linuxMinimal or buildPackages.utillinuxMinimal)];
|
||||
|
||||
|
|
|
@ -1050,7 +1050,7 @@ struct CmdRepl : InstallablesCommand
|
|||
evalSettings.pureEval = false;
|
||||
}
|
||||
|
||||
void prepare()
|
||||
void prepare() override
|
||||
{
|
||||
if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && this->_installables.size() >= 1) {
|
||||
warn("future versions of Nix will require using `--file` to load a file");
|
||||
|
|
|
@ -37,6 +37,85 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
struct TraceData {
|
||||
// Dummy
|
||||
std::string file;
|
||||
size_t line;
|
||||
|
||||
static TraceData fromPos(Pos &p) {
|
||||
return TraceData {
|
||||
p.file,
|
||||
p.line
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Data, size_t size>
|
||||
struct TracingChunk {
|
||||
|
||||
struct Entry {
|
||||
uint64_t ts_entry;
|
||||
uint64_t ts_exit;
|
||||
Data data;
|
||||
};
|
||||
|
||||
struct EntryRAII {
|
||||
Entry* e;
|
||||
EntryRAII(Entry* e, Data d) : e(e) {
|
||||
e->ts_entry = now();
|
||||
e->data = d;
|
||||
}
|
||||
|
||||
~EntryRAII() {
|
||||
e->ts_exit = now();
|
||||
}
|
||||
};
|
||||
|
||||
Entry data[size];
|
||||
size_t pos;
|
||||
|
||||
TracingChunk(): pos(0) {}
|
||||
|
||||
|
||||
inline bool has_capacity() const {
|
||||
return pos < size - 1;
|
||||
}
|
||||
|
||||
inline EntryRAII create(Data d) {
|
||||
// assert(has_capacity()); -- we are writing C++ to go fast, who cares about correctness?!?
|
||||
auto e = &data[pos++];
|
||||
return EntryRAII(e, d);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Data, size_t chunk_size=4096>
|
||||
struct TracingBuffer {
|
||||
|
||||
typedef TracingChunk<Data, chunk_size> TC;
|
||||
// Linked-list of all the chunks that we know about, the last chunk in the list is the latest
|
||||
std::list<TC> chunks;
|
||||
TC& current_chunk; // FIXME: undefined before alloc_new_chunk
|
||||
|
||||
TracingBuffer() {
|
||||
alloc_next_chunk();
|
||||
}
|
||||
|
||||
inline void alloc_next_chunk() {
|
||||
current_chunk = chunks.emplace_back(TC());
|
||||
}
|
||||
|
||||
inline TC::EntryRAII create(Data d) {
|
||||
if (unlikely(!current_chunk.has_capacity())) {
|
||||
alloc_next_chunk();
|
||||
}
|
||||
|
||||
return current_chunk.create(d);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<TracingBuffer<TraceData>> trace;
|
||||
|
||||
|
||||
static char * allocString(size_t size)
|
||||
{
|
||||
char * t;
|
||||
|
@ -175,6 +254,8 @@ void Value::print(const SymbolTable & symbols, std::ostream & str,
|
|||
case tFloat:
|
||||
str << fpoint;
|
||||
break;
|
||||
case tBlackhole:
|
||||
str << "<BLACKHOLE - currently evaluating this attribute>";
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
@ -1269,6 +1350,13 @@ void EvalState::cacheFile(
|
|||
|
||||
void EvalState::eval(Expr * e, Value & v)
|
||||
{
|
||||
|
||||
auto t; // RAII container to ensure that exiting the call actually calls the destructor, actual type is std::optional<TracingChunk::EntryRAII>
|
||||
|
||||
if (trace) {
|
||||
t = std::optional(trace->create(TraceData::fromPos(e->getPos())));
|
||||
}
|
||||
|
||||
e->eval(*this, baseEnv, v);
|
||||
}
|
||||
|
||||
|
|
|
@ -503,7 +503,7 @@ public:
|
|||
return s[0];
|
||||
}
|
||||
|
||||
virtual void setPrintBuildLogs(bool printBuildLogs)
|
||||
void setPrintBuildLogs(bool printBuildLogs) override
|
||||
{
|
||||
this->printBuildLogs = printBuildLogs;
|
||||
}
|
||||
|
|
|
@ -154,13 +154,9 @@ StringSet Settings::getDefaultExtraPlatforms()
|
|||
// machines. Note that we can’t force processes from executing
|
||||
// x86_64 in aarch64 environments or vice versa since they can
|
||||
// always exec with their own binary preferences.
|
||||
if (pathExists("/Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist") ||
|
||||
pathExists("/System/Library/LaunchDaemons/com.apple.oahd.plist")) {
|
||||
if (std::string{SYSTEM} == "x86_64-darwin")
|
||||
extraPlatforms.insert("aarch64-darwin");
|
||||
else if (std::string{SYSTEM} == "aarch64-darwin")
|
||||
extraPlatforms.insert("x86_64-darwin");
|
||||
}
|
||||
if (std::string{SYSTEM} == "aarch64-darwin" &&
|
||||
runProgram(RunOptions {.program = "arch", .args = {"-arch", "x86_64", "/usr/bin/true"}, .mergeStderrToStdout = true}).first == 0)
|
||||
extraPlatforms.insert("x86_64-darwin");
|
||||
#endif
|
||||
|
||||
return extraPlatforms;
|
||||
|
|
Loading…
Reference in New Issue