2323#include <assert.h>
2424#include <errno.h>
2525#include <inttypes.h>
26+ #include <stdarg.h>
2627#include <stdint.h>
2728#include <stdio.h>
2829#include <stdlib.h>
@@ -84,6 +85,20 @@ static void errnoAndExit(const char *message) {
8485#define DEBUG_LOG (fmt , ...) (void)0
8586#endif
8687
88+ #ifdef __clang__
89+ __attribute((__format__ (__printf__ , 2 , 3 )))
90+ #endif
91+ static void
92+ indented_printf (unsigned indentLevel , const char * fmt , ...) {
93+ for (unsigned i = 0 ; i < indentLevel ; i ++ )
94+ fputs (" " , stdout );
95+
96+ va_list args ;
97+ va_start (args , fmt );
98+ vprintf (fmt , args );
99+ va_end (args );
100+ }
101+
87102static const size_t ReadEnd = 0 ;
88103static const size_t WriteEnd = 1 ;
89104
@@ -774,10 +789,40 @@ int reflectEnumValue(SwiftReflectionContextRef RC,
774789
775790}
776791
777- int reflectAsyncTask (SwiftReflectionContextRef RC ,
778- const PipeMemoryReader * Reader ) {
779- uintptr_t AsyncTaskInstance = PipeMemoryReader_receiveInstanceAddress (Reader );
780- printf ("Async task %#" PRIx64 "\n" , (uint64_t )AsyncTaskInstance );
792+ static int reflectAsyncTaskInstance (SwiftReflectionContextRef RC ,
793+ uintptr_t AsyncTaskInstance ,
794+ const PipeMemoryReader * Reader ,
795+ unsigned indentLevel ) {
796+ indented_printf (indentLevel , "Async task %#" PRIx64 "\n" ,
797+ (uint64_t )AsyncTaskInstance );
798+
799+ swift_async_task_info_t TaskInfo =
800+ swift_reflection_asyncTaskInfo (RC , AsyncTaskInstance );
801+ if (TaskInfo .Error ) {
802+ printf ("swift_reflection_asyncTaskInfo failed: %s\n" , TaskInfo .Error );
803+ } else {
804+ indented_printf (indentLevel , "id %" PRIu64 "\n" , TaskInfo .Id );
805+ indented_printf (indentLevel , "enqueuePriority %u\n" ,
806+ TaskInfo .EnqueuePriority );
807+ if (TaskInfo .ChildTaskCount > 0 ) {
808+ indented_printf (indentLevel , "children = {\n" );
809+
810+ // The memory for ChildTasks is only valid until the next Remote Mirror
811+ // call, so we need to copy it.
812+ swift_reflection_ptr_t * ChildTasks =
813+ calloc (TaskInfo .ChildTaskCount , sizeof (swift_reflection_ptr_t ));
814+ memcpy (ChildTasks , TaskInfo .ChildTasks ,
815+ TaskInfo .ChildTaskCount * sizeof (swift_reflection_ptr_t ));
816+
817+ for (unsigned i = 0 ; i < TaskInfo .ChildTaskCount ; i ++ )
818+ reflectAsyncTaskInstance (RC , ChildTasks [i ], Reader , indentLevel + 1 );
819+
820+ free (ChildTasks );
821+ indented_printf (indentLevel , "}\n" );
822+ } else {
823+ indented_printf (indentLevel , "children = {}\n" );
824+ }
825+ }
781826
782827 swift_async_task_slab_return_t SlabPtrResult =
783828 swift_reflection_asyncTaskSlabPointer (RC , AsyncTaskInstance );
@@ -787,33 +832,67 @@ int reflectAsyncTask(SwiftReflectionContextRef RC,
787832 } else {
788833 swift_reflection_ptr_t SlabPtr = SlabPtrResult .SlabPtr ;
789834 while (SlabPtr ) {
790- printf (" Slab pointer %#" PRIx64 "\n" , (uint64_t )SlabPtr );
835+ indented_printf (indentLevel , " Slab pointer %#" PRIx64 "\n" ,
836+ (uint64_t )SlabPtr );
791837 swift_async_task_slab_allocations_return_t AllocationsResult =
792838 swift_reflection_asyncTaskSlabAllocations (RC , SlabPtr );
793839 if (AllocationsResult .Error ) {
794- printf ("swift_reflection_asyncTaskSlabAllocations failed: %s\n" ,
795- AllocationsResult .Error );
840+ indented_printf (
841+ indentLevel ,
842+ "swift_reflection_asyncTaskSlabAllocations failed: %s\n" ,
843+ AllocationsResult .Error );
796844 SlabPtr = 0 ;
797845 } else {
798- printf ( " Slab size %" PRIu64 "\n" ,
799- (uint64_t )AllocationsResult .SlabSize );
846+ indented_printf ( indentLevel , " Slab size %" PRIu64 "\n" ,
847+ (uint64_t )AllocationsResult .SlabSize );
800848 for (unsigned i = 0 ; i < AllocationsResult .ChunkCount ; i ++ ) {
801849 swift_async_task_allocation_chunk_t Chunk =
802850 AllocationsResult .Chunks [i ];
803- printf (" Chunk at %#" PRIx64 " length %u kind %u\n" ,
804- (uint64_t )Chunk .Start , Chunk .Length , Chunk .Kind );
851+ indented_printf (indentLevel ,
852+ " Chunk at %#" PRIx64 " length %u kind %u\n" ,
853+ (uint64_t )Chunk .Start , Chunk .Length , Chunk .Kind );
805854 }
806855 SlabPtr = AllocationsResult .NextSlab ;
807856 }
808857 }
809858 }
810859
811- printf ("\n\n" );
812- PipeMemoryReader_sendDoneMessage (Reader );
860+ if (indentLevel == 0 ) {
861+ printf ("\n\n" );
862+ }
813863 fflush (stdout );
814864 return 1 ;
815865}
816866
867+ int reflectAsyncTask (SwiftReflectionContextRef RC ,
868+ const PipeMemoryReader * Reader ) {
869+ uintptr_t AsyncTaskInstance = PipeMemoryReader_receiveInstanceAddress (Reader );
870+ int result = reflectAsyncTaskInstance (RC , AsyncTaskInstance , Reader , 0 );
871+ PipeMemoryReader_sendDoneMessage (Reader );
872+ return result ;
873+ }
874+
875+ int logString (SwiftReflectionContextRef RC , const PipeMemoryReader * Reader ) {
876+ #pragma clang diagnostic push
877+ #pragma clang diagnostic ignored "-Wcast-qual"
878+ void * Context = (void * )Reader ;
879+ #pragma clang diagnostic pop
880+
881+ swift_addr_t StringPointer = PipeMemoryReader_receiveInstanceAddress (Context );
882+ uint64_t StringLength =
883+ PipeMemoryReader_getStringLength (Context , StringPointer );
884+
885+ void * FreeContext ;
886+ // Read length+1 bytes to get the NUL terminator too.
887+ const void * String = PipeMemoryReader_readBytes (
888+ Context , StringPointer , StringLength + 1 , & FreeContext );
889+
890+ printf ("%s\n" , (const char * )String );
891+ PipeMemoryReader_freeBytes (Context , String , FreeContext );
892+
893+ PipeMemoryReader_sendDoneMessage (Context );
894+ return 1 ;
895+ }
817896
818897int doDumpHeapInstance (const char * BinaryFilename , PipeMemoryReader * Reader ) {
819898#if defined(_WIN32 )
@@ -926,6 +1005,11 @@ int doDumpHeapInstance(const char *BinaryFilename, PipeMemoryReader *Reader) {
9261005 return EXIT_SUCCESS ;
9271006 break ;
9281007 }
1008+ case LogString : {
1009+ if (!logString (RC , Reader ))
1010+ return EXIT_SUCCESS ;
1011+ break ;
1012+ }
9291013 case None :
9301014 swift_reflection_destroyReflectionContext (RC );
9311015 printf ("Done.\n" );
0 commit comments