Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
be9867e
Started the draft for the watch tower.
ivdiazsa Nov 10, 2022
e79ae66
Parsing command-line arguments done.
ivdiazsa Nov 11, 2022
b17eef2
Removed auto-generated file.
ivdiazsa Nov 11, 2022
d40ad9e
Added an example I made on how to run processes from C/C++ :)
ivdiazsa Nov 12, 2022
6cc9e9e
Perfect arg parsing done!
ivdiazsa Nov 16, 2022
fcd9f1a
Seems to be working?
ivdiazsa Nov 16, 2022
1c7f46c
Watchdog is functional now!
ivdiazsa Nov 17, 2022
ec90d1e
Fixed a nuisance with the Windows compiler messing with Linux code, b…
ivdiazsa Nov 22, 2022
b157904
Got the Windows draft working, at long last.
ivdiazsa Nov 23, 2022
36a75f0
Added initial linking of the watcher to the repo's build scripts. Not…
ivdiazsa Dec 6, 2022
c4f2009
Moved the watcher to the CoreCLR project. Not yet functional though...
ivdiazsa Dec 6, 2022
e8b13a5
Got it to build on Windows!
ivdiazsa Dec 7, 2022
b476ad2
Builds and Works on Linux!
ivdiazsa Dec 7, 2022
f74fb2e
Fixed a slowdown with the watcher.
ivdiazsa Dec 8, 2022
958dc29
Forgot to not leak memory :)
ivdiazsa Dec 8, 2022
67e25fe
This is C++, not C.
ivdiazsa Dec 8, 2022
7ef09b2
Bash scripts now call the watcher, but watcher still crashes when bui…
ivdiazsa Dec 14, 2022
226ea36
Renamed variable.
ivdiazsa Dec 14, 2022
5fbd787
FIXED THE LINUX PART!
ivdiazsa Dec 14, 2022
0ff6b8d
Started implementing the constant flow of logs. Had to save my progress.
ivdiazsa Dec 16, 2022
8f21b9c
TEMP LOG BUILDS!
ivdiazsa Dec 17, 2022
c7fc541
TEMP LOGS WORK!
ivdiazsa Dec 17, 2022
4f658e2
Updated with main.
ivdiazsa Feb 15, 2023
a88e48c
Test Watcher seems to be working on Linux and MacOS.
ivdiazsa Feb 22, 2023
8fceb44
Updated the Helix Commands with the watcher now included, and removed…
ivdiazsa Feb 22, 2023
064b9b0
Fixed build issue in the watcher's Windows version.
ivdiazsa Feb 22, 2023
2cb9270
Apparently works on Windows now too?
ivdiazsa Feb 23, 2023
450eba9
Fixed build issue with Windows x86.
ivdiazsa Feb 23, 2023
eba2bcd
Fixed issue where we were not building the watcher in certain subsets…
ivdiazsa Feb 24, 2023
d68d16c
Fixed yet another Windows issue.
ivdiazsa Feb 27, 2023
998965c
Used ExeSuffix instead of recomputing it and excluded Browser-Wasm
ivdiazsa Feb 27, 2023
7cb4e89
Changed the Helix Correlation Payloads to bundle the whole watchdog d…
ivdiazsa Mar 1, 2023
2ba916a
Changed the scripts to use the test watcher in the Core_Root, instead…
ivdiazsa Mar 3, 2023
a712352
Fixed undeclared variable in Windows test scripts.
ivdiazsa Mar 3, 2023
0cc8875
Addressed PR feedback comments.
ivdiazsa Mar 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Perfect arg parsing done!
  • Loading branch information
ivdiazsa committed Nov 16, 2022
commit 6cc9e9eabe707e995ff164074b745e283c764b67
106 changes: 56 additions & 50 deletions src/native/cpp-corerun-watch-tower/watchy-tower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdarg>
#include <vector>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>

struct configuration
{
configuration() = default;

long int timeout;
const char *corerun_path;
const char *corerun_args;
std::vector<const char *> corerun_argv;
};

static void display_usage();
static bool parse_args(const int, const char *[], configuration&);
static int run_timed_process(configuration&);

int main(const int argc, const char *argv[])
{
Expand All @@ -24,9 +31,13 @@ int main(const int argc, const char *argv[])
if (!parse_args(argc, argv, config))
return EXIT_FAILURE;

// These printf's are just for general info during development. They will
// be removed before merging the PR.
printf("Timeout Given: %ld\n", config.timeout);
printf("Corerun Path Given: %s\n", config.corerun_path);
printf("Corerun Arguments Given: %s\n", config.corerun_args);
printf("Corerun Arguments Given:\n");
int r = run_timed_process(config);
printf("%d\n", r);
return EXIT_SUCCESS;
}

Expand Down Expand Up @@ -75,14 +86,13 @@ static bool parse_args(const int argc, const char *argv[], configuration& config
}
else if (strcmp(arg, "-args") == 0 || strcmp(arg, "--args") == 0)
{
if (++i < argc)
// The args flag has to come last, since we can't know beforehand
// how many of the following arguments belong to this flag. So, making
// it last-only, we can assume it's until we're done processing
// the argument vector.
while (++i < argc)
{
config.corerun_args = argv[i];
}
else
{
fprintf(stderr, "Option '%s': Missing arguments for corerun.\n", arg);
return false;
config.corerun_argv.push_back(argv[i]);
}
}
else if (strcmp(arg, "-h") == 0 || strcmp(arg, "--h") == 0 || strcmp(arg, "-?") == 0)
Expand All @@ -99,86 +109,82 @@ static bool parse_args(const int argc, const char *argv[], configuration& config
return true;
}

/* Little example of forking a child process, and finishing it instantly if it
* takes longer than a certain amount of time.

#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>

int run_timed_process(const long, const int, const char *[]);

int main(const int argc, const char *argv[])
{
int result = run_timed_process(3000L, argc-1, &argv[1]);
printf("App Exit Code: %d\n", result);
return 0;
}

int run_timed_process(const long timeout_ms, const int program_argc, const char *program_argv[])
static int run_timed_process(configuration& config)
{
// for (int i = 0; i < program_argc; i++)
// printf("Argv[%d] = %s\n", i, program_argv[i]);
//
const int check_interval = 1000;
const int check_interval_ms = 1000;
int check_count = 0;
char *args[program_argc];
int corerun_argc = config.corerun_argv.size();

// Since our corerun_argv only contains the actual arguments to corerun,
// but the execv() call expects a list including the name of the executable,
// we make an additional slot in our list to add it.
char *program_args[corerun_argc + 1];
program_args[0] = (char *) config.corerun_path;

pid_t child_pid;
int child_status;
int w;

for (int i = 0; i < program_argc; i++)
// The calls to execute child processes require a char * array.
for (int i = 0; i < corerun_argc; i++)
{
args[i] = (char *)program_argv[i];
// We're using index+1 to account for the corerun executable path stored
// at index 0.
program_args[i+1] = (char *) config.corerun_argv.at(i);
}

printf("Forking!\n");
for (int j = 0; j <= corerun_argc; j++)
printf("At [%d]: %s\n", j, program_args[j]);
return 100;

child_pid = fork();

if (child_pid < 0)
{
// Fork failed. No memory remaining available :(
printf("Fork failed... Returning ENOMEM.\n");
// Fork failed. No memory available.
printf("Fork failed... Out of memory.\n");
return ENOMEM;
}
else if (child_pid == 0)
{
// Instructions for child process!
printf("Fork successful! Running child process now...\n");
execv(args[0], &args[0]);
// Instructions for the child process!

// Run the test binary and exit unsuccessfully if it's killed or dies for
// whatever reason.
execv(program_args[0], &program_args[0]);
_exit(EXIT_FAILURE);
}
else
{
// Instructions for the parent process!

// Wait for the child process (running test) to finish, while keeping
// track of how long it's been running.
do
{
// Instructions for the parent process!
w = waitpid(child_pid, &child_status, WNOHANG);

// Something went very wrong.
if (w == -1)
return EINVAL;

usleep(check_interval * 1000);
// Wait a bit before checking the test process' status again.
// Usleep() takes its argument in microseconds, hence we multiply
// by 1000 our interval in milliseconds.
usleep(check_interval_ms * 1000);

if (w)
{
if (WIFEXITED(child_status))
{
printf("Child process exited by signal %d.\n", WEXITSTATUS(child_status));
// Our test run completed successfully.
return WEXITSTATUS(child_status);
}
}
} while (check_count++ < (timeout_ms / check_interval));
} while (check_count++ < (config.timeout / check_interval_ms));
}

printf("Child process took too long. Timed out... Exiting...\n");
printf("Test process took too long to complete, and timed out.\n");
kill(child_pid, SIGKILL);
return ETIMEDOUT;
}

*/