@@ -127,8 +127,13 @@ static bool EvalContextClassPut(EvalContext *ctx, const char *ns, const char *na
127127static const char * EvalContextCurrentNamespace (const EvalContext * ctx );
128128static ClassRef IDRefQualify (const EvalContext * ctx , const char * id );
129129
130- static EventFrame * EventFrameCreate (char * type , const char * name , const char * source , SourceOffset offset );
130+ static EventFrame * EventFrameCreate (char * type , const char * name , const char * source , SourceOffset offset , char * id );
131131static void EventFrameDestroy (EventFrame * event );
132+
133+ static char * BundleGetCallStackID (const Bundle * bp );
134+ static char * PromiseGetCallStackID (const Promise * pp );
135+ static char * FunctionGetCallStackID (const FnCall * fp );
136+
132137static EventFrame * BundleToEventFrame (const Bundle * bp );
133138static EventFrame * PromiseToEventFrame (const Promise * pp );
134139static EventFrame * FunctionToEventFrame (const FnCall * fp );
@@ -346,6 +351,20 @@ static StackFrame *LastStackFrameByType(const EvalContext *ctx, StackFrameType t
346351 return NULL ;
347352}
348353
354+ static StackFrame * LastStackFrameByEvent (const EvalContext * ctx )
355+ {
356+ for (size_t i = 0 ; i < SeqLength (ctx -> stack ); i ++ )
357+ {
358+ StackFrame * frame = LastStackFrame (ctx , i );
359+ if (frame -> event != NULL )
360+ {
361+ return frame ;
362+ }
363+ }
364+
365+ return NULL ;
366+ }
367+
349368static LogLevel AdjustLogLevel (LogLevel base , LogLevel adjust )
350369{
351370 if (adjust == -1 )
@@ -1436,7 +1455,22 @@ void EvalContextStackPushBundleFrame(EvalContext *ctx, const Bundle *owner, cons
14361455 assert (ctx != NULL );
14371456 assert (!LastStackFrame (ctx , 0 ) || LastStackFrame (ctx , 0 )-> type == STACK_FRAME_TYPE_PROMISE_ITERATION );
14381457
1439- EvalContextStackPushFrame (ctx , StackFrameNewBundle (owner , inherits_previous , ctx -> profiling ));
1458+ StackFrame * prev_frame = LastStackFrameByEvent (ctx );
1459+ StackFrame * frame = StackFrameNewBundle (owner , inherits_previous , ctx -> profiling );
1460+
1461+ EventFrame * pushed_event = frame -> event ;
1462+ EvalContextStackPushFrame (ctx , frame );
1463+ if (pushed_event != NULL )
1464+ {
1465+ if (prev_frame == NULL || prev_frame -> event == NULL )
1466+ {
1467+ pushed_event -> stacktrace = SafeStringDuplicate (pushed_event -> id );
1468+ }
1469+ else
1470+ {
1471+ pushed_event -> stacktrace = StringFormat ("%s;%s" , prev_frame -> event -> stacktrace , pushed_event -> id );
1472+ }
1473+ }
14401474
14411475 if (RlistLen (args ) > 0 )
14421476 {
@@ -1516,9 +1550,22 @@ void EvalContextStackPushPromiseFrame(EvalContext *ctx, const Promise *owner)
15161550
15171551 EvalContextVariableClearMatch (ctx );
15181552
1553+ StackFrame * prev_frame = LastStackFrameByEvent (ctx );
15191554 StackFrame * frame = StackFrameNewPromise (owner , ctx -> profiling );
15201555
15211556 EvalContextStackPushFrame (ctx , frame );
1557+ EventFrame * pushed_event = frame -> event ;
1558+ if (pushed_event != NULL )
1559+ {
1560+ if (prev_frame == NULL || prev_frame -> event == NULL )
1561+ {
1562+ pushed_event -> stacktrace = SafeStringDuplicate (pushed_event -> id );
1563+ }
1564+ else
1565+ {
1566+ pushed_event -> stacktrace = StringFormat ("%s;%s" , prev_frame -> event -> stacktrace , pushed_event -> id );
1567+ }
1568+ }
15221569
15231570 // create an empty table
15241571 frame -> data .promise .vars = VariableTableNew ();
@@ -3891,7 +3938,7 @@ void EvalContextSetProfiling(EvalContext *ctx, bool profiling)
38913938 ctx -> profiling = profiling ;
38923939}
38933940
3894- static EventFrame * EventFrameCreate (char * type , const char * name , const char * source , SourceOffset offset )
3941+ static EventFrame * EventFrameCreate (char * type , const char * name , const char * source , SourceOffset offset , char * id )
38953942{
38963943 EventFrame * event = (EventFrame * ) xmalloc (sizeof (EventFrame ));
38973944
@@ -3900,7 +3947,8 @@ static EventFrame *EventFrameCreate(char *type, const char *name, const char *so
39003947 event -> filename = GetAbsolutePath (source );
39013948 event -> elapsed = 0 ;
39023949 event -> offset = offset ;
3903- event -> id = StringFormat ("%s_%s_%s_%ld_%ld" , type , name , source , offset .start , offset .line );
3950+ event -> id = id ;
3951+ event -> stacktrace = "" ;
39043952
39053953 return event ;
39063954}
@@ -3926,6 +3974,7 @@ static JsonElement *EventToJson(EventFrame *event)
39263974 JsonObjectAppendString (json_event , "filename" , event -> filename );
39273975 JsonObjectAppendString (json_event , "id" , event -> id );
39283976 JsonObjectAppendInteger64 (json_event , "elapsed" , event -> elapsed );
3977+ JsonObjectAppendString (json_event , "callstack" , event -> stacktrace );
39293978
39303979 JsonElement * offset = JsonObjectCreate (4 );
39313980 JsonObjectAppendInteger (offset , "start" , event -> offset .start );
@@ -3941,19 +3990,19 @@ static JsonElement *EventToJson(EventFrame *event)
39413990static EventFrame * BundleToEventFrame (const Bundle * bp )
39423991{
39433992 assert (bp != NULL );
3944- return EventFrameCreate ("bundle" , bp -> name , bp -> source_path , bp -> offset );
3993+ return EventFrameCreate ("bundle" , bp -> name , bp -> source_path , bp -> offset , BundleGetCallStackID ( bp ) );
39453994}
39463995
39473996static EventFrame * PromiseToEventFrame (const Promise * pp )
39483997{
39493998 assert (pp != NULL );
3950- return EventFrameCreate ("promise" , PromiseGetPromiseType (pp ), PromiseGetBundle (pp )-> source_path , pp -> offset );
3999+ return EventFrameCreate ("promise" , PromiseGetPromiseType (pp ), PromiseGetBundle (pp )-> source_path , pp -> offset , PromiseGetCallStackID ( pp ) );
39514000}
39524001
39534002static EventFrame * FunctionToEventFrame (const FnCall * fp )
39544003{
39554004 assert (fp != NULL );
3956- return EventFrameCreate ("function" , fp -> name , PromiseGetBundle (fp -> caller )-> source_path , fp -> caller -> offset );
4005+ return EventFrameCreate ("function" , fp -> name , PromiseGetBundle (fp -> caller )-> source_path , fp -> caller -> offset , FunctionGetCallStackID ( fp ) );
39574006}
39584007
39594008void EvalContextAddFunctionEvent (EvalContext * ctx , const FnCall * fp , int64_t start )
@@ -4022,19 +4071,24 @@ void EvalContextProfilingEnd(EvalContext *ctx, const Policy *policy)
40224071
40234072 ctx -> profiler .elapsed = end - start ;
40244073
4025- HashMap * map = SumEventFrames (ctx -> profiler .events );
4074+ // HashMap *map = SumEventFrames(ctx->profiler.events);
40264075 JsonElement * profiling = JsonObjectCreate (2 );
40274076
40284077 JsonElement * json_policy = PolicyToJson (policy );
40294078 JsonObjectAppendObject (profiling , "policy" , json_policy );
40304079
40314080 JsonElement * events = JsonArrayCreate (10 );
40324081 {
4033- HashMapIterator iter = HashMapIteratorInit (map );
4034- MapKeyValue * mkv ;
4035- while ((mkv = HashMapIteratorNext (& iter )) != NULL )
4082+ // HashMapIterator iter = HashMapIteratorInit(map);
4083+ // MapKeyValue *mkv;
4084+ // while ((mkv = HashMapIteratorNext(&iter)) != NULL)
4085+ // {
4086+ // EventFrame *event = mkv->value;
4087+ // JsonArrayAppendObject(events, EventToJson(event));
4088+ // }
4089+ for (size_t i = 0 ; i < SeqLength (ctx -> profiler .events ); i ++ )
40364090 {
4037- EventFrame * event = mkv -> value ;
4091+ EventFrame * event = SeqAt ( ctx -> profiler . events , i ) ;
40384092 JsonArrayAppendObject (events , EventToJson (event ));
40394093 }
40404094 }
@@ -4047,3 +4101,19 @@ void EvalContextProfilingEnd(EvalContext *ctx, const Policy *policy)
40474101
40484102 JsonDestroy (profiling );
40494103}
4104+
4105+
4106+ static char * BundleGetCallStackID (const Bundle * bp )
4107+ {
4108+ return StringFormat ("bundle_%s_%s:%s_%s:%ld_%ld-%ld" , bp -> type , bp -> ns , bp -> name , bp -> source_path , bp -> offset .line , bp -> offset .start , bp -> offset .end );
4109+ }
4110+
4111+ static char * PromiseGetCallStackID (const Promise * pp )
4112+ {
4113+ return StringFormat ("promise_%s_%ld_%ld-%ld" , PromiseGetPromiseType (pp ), pp -> offset .line , pp -> offset .start , pp -> offset .end );
4114+ }
4115+
4116+ static char * FunctionGetCallStackID (const FnCall * fp )
4117+ {
4118+ return StringFormat ("function_%s_%ld_%ld-%ld" , fp -> name , fp -> caller -> offset .line , fp -> caller -> offset .start , fp -> caller -> offset .end );
4119+ }
0 commit comments