Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit ecf0c9f

Browse files
authored
Merge branch 'main' into debuginfo-cache
2 parents 542cbed + e603fa9 commit ecf0c9f

File tree

9 files changed

+138
-28
lines changed

9 files changed

+138
-28
lines changed

docs/troubleshooting.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Troubleshooting issues with binaries
2+
3+
The agent exposes some validation tools to help troubleshoot issues with a binary.
4+
This allows the user to debug and fix errors that could prevent a job from running.
5+
6+
## Using the validation tools
7+
Download a zip file containing the agent binaries:
8+
9+
```
10+
onefuzz tools get <destination_folder>
11+
```
12+
13+
Extract the zip file in a folder of your choice.
14+
Navigate to the folder that matches your os.
15+
Run the following command to see the tools available:
16+
`onefuzz-agent.exe validate --help`
17+
The current list of commands are:
18+
- run_setup : Run the setup script
19+
- validate_libfuzzer: Validate the libfuzzer target
20+
- execution_log: Get the execution logs to debug loading issues
21+
22+
More tools might be added in the future so please refer the help command to get the most up to date list.
23+
24+
25+
## In a docker container
26+
27+
It could also be helpful to run the those command in an environment to closely match the vm where the agent is deployed.
28+
A docker container can help with that scenario.
29+
30+
Make sure [docker](https://docs.docker.com/desktop/) is installed and runs properly.
31+
32+
Navigate to the folder that matches your os in the tools folder created earlier and build the docker container:
33+
34+
```cmd
35+
docker build --t <container_name> .
36+
```
37+
38+
Use the container interactively to execute the validation command:
39+
40+
windows
41+
42+
```
43+
docker run --it --rm --entrypoint powershell <image_name>
44+
```
45+
46+
linux
47+
48+
```
49+
docker run --it --rm --entrypoint bash <image_name>
50+
```
51+
52+
From there you can navigate to the onefuzz directory and execute the validation commands
53+

docs/unmanaged-nodes.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Under the `client_credential` section of the agent config file, update `client_i
7575

7676
Save the config to the file.
7777

78-
### Start the agent.
78+
### Start the agent
7979

8080
Navigate to the folder corresponding to your OS.
8181
Set the necessary environment variable by running the script `set-env.ps1` (for Windows) or `set-env.sh` (for Linux).
@@ -111,7 +111,7 @@ From here you will be able to schedule jobs on that pool and they will run.
111111

112112
## Troubleshooting
113113

114-
### increase the verbosity of the logs
114+
### Increase the verbosity of the logs
115115

116116
It can help when investigating issues to increase the log verbosity. you will need to set the [RUST_LOG](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) environment variable when starting docker
117117

@@ -127,7 +127,7 @@ log_level can be any of
127127
- debug
128128
- trace
129129

130-
### use the container interactively
130+
### Use the container interactively
131131

132132
you can use the container interactively by with the following command
133133

@@ -143,7 +143,7 @@ linux
143143
docker run --it --rm --entrypoint bash <image_name>
144144
```
145145

146-
### mount a local folder in the container
146+
### Mount a local folder in the container
147147

148148
docker allows you to [mount](https://docs.docker.com/storage/bind-mounts/#mount-into-a-non-empty-directory-on-the-container) a local folder when running a container
149149

src/agent/onefuzz-agent/src/validations.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use uuid::Uuid;
1111
pub enum ValidationCommand {
1212
/// Run the setup script
1313
RunSetup { setup_folder: PathBuf },
14-
/// Validate the libfuzzer target
14+
/// Validate the libfuzzer target by attempting to run the target by itself and with some of the supplied seeds if provided
1515
ValidateLibfuzzer(ValidationConfig),
16-
/// Get the execution logs to debug loading issues
16+
/// Get the execution logs to debug dll loading issues
1717
ExecutionLog(ValidationConfig),
1818
}
1919

@@ -30,8 +30,6 @@ where
3030
.find('=')
3131
.ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
3232

33-
println!("******** pos: {}", pos);
34-
3533
Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
3634
}
3735

src/agent/onefuzz-task/src/tasks/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,15 @@ impl Config {
228228
match self {
229229
Config::GenericGenerator(c) => {
230230
event!(task_start; EventData::Type = event_type, EventData::ToolName = c.generator_exe.clone());
231+
metric!(task_start; 1.0; EventData::Type = event_type, EventData::ToolName = c.generator_exe.clone());
231232
}
232233
Config::GenericAnalysis(c) => {
233234
event!(task_start; EventData::Type = event_type, EventData::ToolName = c.analyzer_exe.clone());
235+
metric!(task_start; 1.0; EventData::Type = event_type, EventData::ToolName = c.analyzer_exe.clone());
234236
}
235237
_ => {
236238
event!(task_start; EventData::Type = event_type);
239+
metric!(task_start; 1.0; EventData::Type = event_type);
237240
}
238241
}
239242
}

src/agent/onefuzz-task/src/tasks/coverage/generic.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ impl<'a> TaskContext<'a> {
376376
if entry.file_type().await?.is_file() {
377377
if let Err(e) = self.record_input(&entry.path()).await {
378378
event!(coverage_failed; EventData::Path = entry.path().display().to_string());
379+
metric!(coverage_failed; 1.0; EventData::Path = entry.path().display().to_string());
379380
warn!(
380381
"ignoring error recording coverage for input: {}, error: {}",
381382
entry.path().display(),
@@ -407,6 +408,7 @@ impl<'a> TaskContext<'a> {
407408

408409
let s = CoverageStats::new(&self.coverage);
409410
event!(coverage_data; Covered = s.covered, Features = s.features, Rate = s.rate);
411+
metric!(coverage_data; 1.0; Covered = s.covered, Features = s.features, Rate = s.rate);
410412

411413
Ok(())
412414
}

src/agent/onefuzz-task/src/tasks/fuzz/libfuzzer/common.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,12 @@ impl TotalStats {
383383
EventData::Count = self.count,
384384
EventData::ExecsSecond = self.execs_sec
385385
);
386+
metric!(
387+
runtime_stats;
388+
1.0;
389+
EventData::Count = self.count,
390+
EventData::ExecsSecond = self.execs_sec
391+
);
386392
}
387393
}
388394

src/agent/onefuzz-task/src/tasks/report/crash_report.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ impl RegressionReport {
124124
};
125125

126126
if upload_or_save_local(&self, &name, regression_reports).await? {
127-
event!(event; EventData::Path = name);
127+
event!(event; EventData::Path = name.clone());
128+
metric!(event; 1.0; EventData::Path = name.clone());
128129
}
129130
Ok(())
130131
}
@@ -155,14 +156,16 @@ impl CrashTestResult {
155156
if let Some(unique_reports) = unique_reports {
156157
let name = report.unique_blob_name();
157158
if upload_or_save_local(&report, &name, unique_reports).await? {
158-
event!(new_unique_report; EventData::Path = name);
159+
event!(new_unique_report; EventData::Path = report.unique_blob_name());
160+
metric!(new_unique_report; 1.0; EventData::Path = report.unique_blob_name());
159161
}
160162
}
161163

162164
if let Some(reports) = reports {
163165
let name = report.blob_name();
164166
if upload_or_save_local(&report, &name, reports).await? {
165-
event!(new_report; EventData::Path = name);
167+
event!(new_report; EventData::Path = report.blob_name());
168+
metric!(new_report; 1.0; EventData::Path = report.blob_name());
166169
}
167170
}
168171
}
@@ -171,7 +174,8 @@ impl CrashTestResult {
171174
if let Some(no_repro) = no_repro {
172175
let name = report.blob_name();
173176
if upload_or_save_local(&report, &name, no_repro).await? {
174-
event!(new_unable_to_reproduce; EventData::Path = name);
177+
event!(new_unable_to_reproduce; EventData::Path = report.blob_name());
178+
metric!(new_unable_to_reproduce; 1.0; EventData::Path = report.blob_name());
175179
}
176180
}
177181
}

src/agent/onefuzz-telemetry/src/lib.rs

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,33 @@ pub fn track_event(event: &Event, properties: &[EventData]) {
515515
try_broadcast_event(chrono::Utc::now(), event, properties);
516516
}
517517

518+
pub fn track_metric(metric: &Event, value: f64, properties: &[EventData]) {
519+
use appinsights::telemetry::Telemetry;
520+
521+
if let Some(client) = client(ClientType::Instance) {
522+
let mut mtr = appinsights::telemetry::MetricTelemetry::new(metric.as_str(), value);
523+
let props = mtr.properties_mut();
524+
for property in properties {
525+
let (name, val) = property.as_values();
526+
props.insert(name.to_string(), val);
527+
}
528+
client.track(mtr);
529+
}
530+
531+
if let Some(client) = client(ClientType::Microsoft) {
532+
let mut mtr = appinsights::telemetry::MetricTelemetry::new(metric.as_str(), value);
533+
let props = mtr.properties_mut();
534+
535+
for property in properties {
536+
if property.can_share_with_microsoft() {
537+
let (name, val) = property.as_values();
538+
props.insert(name.to_string(), val);
539+
}
540+
}
541+
client.track(mtr);
542+
}
543+
}
544+
518545
pub fn to_log_level(level: &appinsights::telemetry::SeverityLevel) -> log::Level {
519546
match level {
520547
Verbose => log::Level::Debug,
@@ -551,6 +578,27 @@ macro_rules! event {
551578
}};
552579
}
553580

581+
#[macro_export]
582+
macro_rules! log_metrics {
583+
($name: expr; $value: expr; $metrics: expr) => {{
584+
onefuzz_telemetry::track_metric(&$name, $value, &$metrics);
585+
}};
586+
}
587+
588+
#[macro_export]
589+
macro_rules! metric {
590+
($name: expr ; $value: expr ; $($k: path = $v: expr),*) => {{
591+
let mut metrics = Vec::new();
592+
593+
$({
594+
metrics.push($k(From::from($v)));
595+
596+
})*;
597+
598+
log_metrics!($name; $value; metrics);
599+
}};
600+
}
601+
554602
#[macro_export]
555603
macro_rules! log {
556604
($level: expr, $($arg: tt)+) => {{
@@ -597,11 +645,3 @@ macro_rules! critical {
597645
onefuzz_telemetry::log!(onefuzz_telemetry::Critical, $($arg)+);
598646
}}
599647
}
600-
601-
#[macro_export]
602-
macro_rules! metric {
603-
($name: expr, $value: expr) => {{
604-
let client = onefuzz_telemetry::client(onefuzz_telemetry::ClientType::Instance);
605-
client.track_metric($name.into(), $value);
606-
}};
607-
}

src/agent/onefuzz/src/syncdir.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,21 @@ impl SyncedDir {
253253
let file_name = item
254254
.file_name()
255255
.ok_or_else(|| anyhow!("invalid file path"))?;
256-
let file_name_str = file_name.to_string_lossy();
256+
let file_name_event_str = file_name.to_string_lossy();
257+
let file_name_str_metric_str = file_name.to_string_lossy();
257258

258259
// explicitly ignore azcopy temporary files
259260
// https://github.com/Azure/azure-storage-azcopy/blob/main/ste/xfer-remoteToLocal-file.go#L35
260-
if file_name_str.starts_with(".azDownload-") {
261+
if file_name_event_str.starts_with(".azDownload-") {
261262
continue;
262263
}
263264

264-
if ignore_dotfiles && file_name_str.starts_with('.') {
265+
if ignore_dotfiles && file_name_event_str.starts_with('.') {
265266
continue;
266267
}
267268

268-
event!(event.clone(); EventData::Path = file_name_str);
269+
event!(event.clone(); EventData::Path = file_name_event_str);
270+
metric!(event.clone(); 1.0; EventData::Path = file_name_str_metric_str);
269271
let destination = path.join(file_name);
270272
if let Err(err) = fs::copy(&item, &destination).await {
271273
let error_message = format!(
@@ -288,19 +290,21 @@ impl SyncedDir {
288290
let file_name = item
289291
.file_name()
290292
.ok_or_else(|| anyhow!("invalid file path"))?;
291-
let file_name_str = file_name.to_string_lossy();
293+
let file_name_event_str = file_name.to_string_lossy();
294+
let file_name_str_metric_str = file_name.to_string_lossy();
292295

293296
// explicitly ignore azcopy temporary files
294297
// https://github.com/Azure/azure-storage-azcopy/blob/main/ste/xfer-remoteToLocal-file.go#L35
295-
if file_name_str.starts_with(".azDownload-") {
298+
if file_name_event_str.starts_with(".azDownload-") {
296299
continue;
297300
}
298301

299-
if ignore_dotfiles && file_name_str.starts_with('.') {
302+
if ignore_dotfiles && file_name_event_str.starts_with('.') {
300303
continue;
301304
}
302305

303-
event!(event.clone(); EventData::Path = file_name_str);
306+
event!(event.clone(); EventData::Path = file_name_event_str);
307+
metric!(event.clone(); 1.0; EventData::Path = file_name_str_metric_str);
304308
if let Err(err) = uploader.upload(item.clone()).await {
305309
let error_message = format!(
306310
"Couldn't upload file. path:{} dir:{} err:{:?}",

0 commit comments

Comments
 (0)