Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 12 additions & 1 deletion cf-agent/cf-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ static const struct option OPTIONS[] =
{"color", optional_argument, 0, 'C'},
{"no-extensions", no_argument, 0, 'E'},
{"timestamp", no_argument, 0, 'l'},
{"profile", no_argument, 0, 'p'},
/* Only long option for the rest */
{"ignore-preferred-augments", no_argument, 0, 0},
{"log-modules", required_argument, 0, 0},
Expand Down Expand Up @@ -245,6 +246,7 @@ static const char *const HINTS[] =
"Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'",
"Disable extension loading (used while upgrading)",
"Log timestamps on each line of log output",
"Output diagnostic of bundle execution",
"Ignore def_preferred.json file in favor of def.json",
"Enable even more detailed debug logging for specific areas of the implementation. Use together with '-d'. Use --log-modules=help for a list of available modules",
"Do not load augments (def.json)",
Expand Down Expand Up @@ -323,7 +325,13 @@ int main(int argc, char *argv[])

BeginAudit();

EvalContextEventStackClear(ctx);

EvalContextPushEvent(ctx, EventFrameNew("policy", "policy", "null", "null", (SourceOffset) {0}));
KeepPromises(ctx, policy, config);
EvalContextPopEvent(ctx);

EvalContextPrintRoot(ctx);

if (EvalAborted(ctx))
{
Expand Down Expand Up @@ -523,7 +531,7 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv)
FreeFixedStringArray(argc_new, argv_tmp);

int longopt_idx;
while ((c = getopt_long(argc_new, argv_new, "tdvnKIf:g:w:D:N:VxMB:b:hC::ElT::",
while ((c = getopt_long(argc_new, argv_new, "tdvnKIf:g:w:D:N:VxMB:b:hC::ElT::p",
OPTIONS, &longopt_idx))
!= -1)
{
Expand Down Expand Up @@ -689,6 +697,9 @@ static GenericAgentConfig *CheckOpts(int argc, char **argv)
}

break;
case 'p':
printf("profiling activated!\n");
break;

/* long options only */
case 0:
Expand Down
133 changes: 133 additions & 0 deletions libpromises/eval_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@
/* ONLY INITIALIZED WHEN NON-EMPTY, OTHERWISE NULL */
RemoteVarPromisesMap *remote_var_promises;

EventFrame *root;
Seq *event_stack;

bool dump_reports;
};

Expand Down Expand Up @@ -1093,6 +1096,8 @@

ctx->dump_reports = false;

ctx->event_stack = SeqNew(10, EventFrameDestroy);

return ctx;
}

Expand Down Expand Up @@ -1438,6 +1443,7 @@
}
VariableTableIteratorDestroy(iter);
}
EvalContextPushEvent(ctx, EventFrameNew("bundle", owner->name, owner->ns, GetAbsolutePath(owner->source_path), owner->offset));

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter owner in EvalContextStackPushBundleFrame() is dereferenced without an explicit null-check

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter owner in EvalContextStackPushBundleFrame() is dereferenced without an explicit null-check

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter owner in EvalContextStackPushBundleFrame() is dereferenced without an explicit null-check

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter owner in EvalContextStackPushBundleFrame() is dereferenced without an explicit null-check
}

void EvalContextStackPushBodyFrame(EvalContext *ctx, const Promise *caller, const Body *body, const Rlist *args)
Expand Down Expand Up @@ -1475,6 +1481,7 @@
{
ScopeMapBodyArgs(ctx, body, args);
}
EvalContextPushEvent(ctx, NULL);
}

void EvalContextStackPushBundleSectionFrame(EvalContext *ctx, const BundleSection *owner)
Expand All @@ -1483,6 +1490,8 @@

StackFrame *frame = StackFrameNewBundleSection(owner);
EvalContextStackPushFrame(ctx, frame);

EvalContextPushEvent(ctx, NULL);
}

void EvalContextStackPushPromiseFrame(EvalContext *ctx, const Promise *owner)
Expand Down Expand Up @@ -1552,6 +1561,8 @@
RvalDestroy(final);
}
}

EvalContextPushEvent(ctx, EventFrameNew("promise", PromiseGetPromiseType(owner), PromiseGetNamespace(owner), "null", owner->offset));

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter owner in EvalContextStackPushPromiseFrame() is dereferenced without an explicit null-check
}

Promise *EvalContextStackPushPromiseIterationFrame(EvalContext *ctx, const PromiseIterator *iter_ctx)
Expand All @@ -1574,6 +1585,8 @@
EvalContextStackPushFrame(ctx, StackFrameNewPromiseIteration(pexp, iter_ctx));
LoggingPrivSetLevels(CalculateLogLevel(pexp), CalculateReportLevel(pexp));

EvalContextPushEvent(ctx, NULL);

return pexp;
}

Expand Down Expand Up @@ -1623,6 +1636,8 @@

LogDebug(LOG_MOD_EVALCTX, "POPPED FRAME (type %s)",
STACK_FRAME_TYPE_STR[last_frame_type]);

EvalContextPopEvent(ctx);
}

bool EvalContextClassRemove(EvalContext *ctx, const char *ns, const char *name)
Expand Down Expand Up @@ -3847,3 +3862,121 @@
assert(stack_frame != NULL);
return stack_frame->override_immutable;
}

// ##############################################################

static void EventStackPush(EvalContext *ctx, EventFrame *event)
{
SeqAppend(ctx->event_stack, event);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EventStackPush() is dereferenced without an explicit null-check
}

static EventFrame *EventStackPop(EvalContext *ctx)
{
size_t last = SeqLength(ctx->event_stack) - 1;

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EventStackPop() is dereferenced without an explicit null-check
EventFrame *popped = SeqAt(ctx->event_stack, last);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EventStackPop() is dereferenced without an explicit null-check
SeqRemove(ctx->event_stack, last);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EventStackPop() is dereferenced without an explicit null-check

return popped;
}

static EventFrame *EventStackPeek(EvalContext *ctx)
{
size_t last = SeqLength(ctx->event_stack) - 1;

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EventStackPeek() is dereferenced without an explicit null-check
EventFrame *peeked = SeqAt(ctx->event_stack, last);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EventStackPeek() is dereferenced without an explicit null-check

return peeked;
}

// Event

void EventFrameDestroy(EventFrame *event)
{
// SeqDestroy(event->children);
// free(event);
Comment on lines +3894 to +3895

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.
}

EventFrame *EventFrameNew(const char *id, const char *name, const char *ns, const char *source_path, SourceOffset offset)
{
EventFrame *event = (EventFrame *) xmalloc(sizeof(EventFrame));
event->id = id;
event->name = name;
event->ns = ns;
event->source_path = source_path;
event->offset = offset;
event->enlapsed = time(NULL);

event->children = SeqNew(10, EventFrameDestroy);

return event;
}

void EvalContextPushEvent(EvalContext *ctx, EventFrame *event)
{
if (event == NULL)
{
event = EventFrameNew(NULL, NULL, NULL, NULL, (SourceOffset) {0});
}
EventStackPush(ctx, event);
}

void EvalContextPopEvent(EvalContext *ctx)
{
if (SeqLength(ctx->event_stack) == 0)

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EvalContextPopEvent() is dereferenced without an explicit null-check
return;

time_t end = time(NULL);
EventFrame *popped = EventStackPop(ctx);
popped->enlapsed = end - popped->enlapsed; // update time

if (popped->id == NULL) // junk node
{
return;
}

if (SeqLength(ctx->event_stack) < 1)

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EvalContextPopEvent() is dereferenced without an explicit null-check
{
ctx->root = popped;

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EvalContextPopEvent() is dereferenced without an explicit null-check
return;
}

EventFrame *parent = EventStackPeek(ctx);
SeqAppend(parent->children, popped);
}

void EvalContextEventStackClear(EvalContext *ctx)
{
// SeqClear(ctx->event_stack);

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.
ctx->event_stack = SeqNew(10, NULL);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EvalContextEventStackClear() is dereferenced without an explicit null-check
}

static void EventFrameTraverse(const EventFrame *node, int depth)
{
if (node == NULL)
return;

// Print indentation
for (int i = 0; i < depth; i++)
printf(" ");

// Print node info
printf("• [%lds] %s:%s (ns=%s, src=%s)\n",
node->enlapsed,
node->id ? node->id : "(no-id)",
node->name ? node->name : "(no-name)",
node->ns ? node->ns : "(no-ns)",
node->source_path ? node->source_path : "(no-src)");

// Recurse through children
size_t len = SeqLength(node->children);
for (size_t i = 0; i < len; i++)
{
EventFrame *child = SeqAt(node->children, i);
EventFrameTraverse(child, depth + 1);
}
}


void EvalContextPrintRoot(EvalContext *ctx)
{
EventFrameTraverse(ctx->root, 0);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter ctx in EvalContextPrintRoot() is dereferenced without an explicit null-check
}
19 changes: 19 additions & 0 deletions libpromises/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ typedef enum
EVAL_OPTION_FULL = 0xFFFFFFFF
} EvalContextOption;

typedef struct {
time_t enlapsed;
char *id; // bundle
char *name; // main
char *ns; // default
char *source_path; // profiler.cf
SourceOffset offset;

Seq *children;
} EventFrame;

EvalContext *EvalContextNew(void);
void EvalContextDestroy(EvalContext *ctx);

Expand Down Expand Up @@ -434,4 +445,12 @@ void EvalContextSetDumpReports(EvalContext *ctx, bool dump_reports);
bool EvalContextGetDumpReports(EvalContext *ctx);
void EvalContextUpdateDumpReports(EvalContext *ctx);


void EventFrameDestroy(EventFrame *event);
EventFrame *EventFrameNew(const char *id, const char *name, const char *ns, const char *source_path, SourceOffset offset);
void EvalContextPushEvent(EvalContext *ctx, EventFrame *event);
void EvalContextPopEvent(EvalContext *ctx);
void EvalContextEventStackClear(EvalContext *ctx);
void EvalContextPrintRoot(EvalContext *ctx);

#endif
2 changes: 2 additions & 0 deletions libpromises/fncall.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,9 @@
WriterClose(fncall_writer);
}

EvalContextPushEvent(ctx, EventFrameNew("function", fp->name, PromiseGetNamespace(fp->caller), "null", fp->caller->offset));

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter caller in FnCallEvaluate() is dereferenced without an explicit null-check
FnCallResult result = CallFunction(ctx, policy, fp, expargs);
EvalContextPopEvent(ctx);

if (result.status == FNCALL_FAILURE)
{
Expand Down
97 changes: 97 additions & 0 deletions libpromises/ignoreme.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"type" : "Policy",
"name" : "a38cec43f6896fad9b39595edc122795d0abbb2f",
"file" : "",
"lineno" : 0,
"colno" : 0,
"children" : [
{
"type" : "Bundle",
"name" : "default:main",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 4.0,
"lineno" : 1,
"colno" : 13,
"children" : [
{
"type" : "Promise",
"name" : "classes",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 0.0,
"lineno" : 4,
"colno" : 59,
"children" : [

]
},
{
"type" : "Promise",
"name" : "methods",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 1.0,
"lineno" : 7,
"colno" : 195,
"children" : [
{
"type" : "Bundle",
"name" : "default:one",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 1.0,
"lineno" : 12,
"colno" : 315,
"children" : [
{
"type" : "Promise",
"name" : "commands",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 1.0,
"lineno" : 15,
"colno" : 368
}
]
}
]
},
{
"type" : "Promise",
"name" : "methods",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 1.0,
"lineno" : 8,
"colno" : 216,
"children" : [
{
"type" : "Bundle",
"name" : "default:two",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 3.0,
"lineno" : 18,
"colno" : 417,
"children" : [
{
"type" : "Promise",
"name" : "commands",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 3.0,
"lineno" : 21,
"colno" : 470
}
]
}
]
},
{
"type" : "Promise",
"name" : "methods",
"file" : "/home/vagrant/hello.cf",
"enlapsed" : 0.0,
"lineno" : 10,
"colno" : 267,
"children" : [

]
}
]
}
]
}
Loading