3434#endif
3535// Include execinfo.h for the native backtrace API. The API is unavailable on AIX
3636// and on some Linux distributions, e.g. Alpine Linux.
37- #if !defined(_AIX) && !(defined(__linux__) && !defined(__GLIBC__))
37+ #if !defined(_AIX) && !(defined(__linux__) && !defined(__GLIBC__)) && !defined(__MVS__)
3838#include < execinfo.h>
3939#endif
4040#include < sys/utsname.h>
4848extern char ** environ;
4949#endif
5050
51+ #ifdef __MVS__
52+ class __auto_ascii {
53+ public:
54+ __auto_ascii ();
55+ ~__auto_ascii ();
56+ };
57+ extern " C" int backtrace (void **buffer, int size);
58+ extern " C" char **backtrace_symbols (void *const *buffer, int size);
59+ extern " C" void *__dlcb_next (void *last);
60+ extern " C" int __dlcb_entry_name (char *buf, int size, void *dlcb);
61+ extern " C" void *__dlcb_entry_addr (void *dlcb);
62+ extern " C" int __find_file_in_path (char *out, int size, const char *envvar, const char *file);
63+ #endif
64+
5165namespace nodereport {
5266
5367using v8::HeapSpaceStatistics;
@@ -138,6 +152,9 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
138152 }
139153
140154 // Open the report file stream for writing. Supports stdout/err, user-specified or (default) generated name
155+ #ifdef __MVS__
156+ __auto_ascii _a;
157+ #endif
141158 std::ofstream outfile;
142159 std::ostream* outstream = &std::cout;
143160 if (!strncmp (filename, " stdout" , sizeof (" stdout" ) - 1 )) {
@@ -420,12 +437,29 @@ static void PrintVersionInformation(std::ostream& out) {
420437 out << " \n OS version: " << os_info.sysname << " " << os_info.release << " "
421438 << os_info.version << " \n " ;
422439#endif
440+ #if defined(__MVS__)
441+ char *r;
442+ __asm (" llgt %0,1208 \n "
443+ " lg %0,88(%0) \n "
444+ " lg %0,8(%0) \n "
445+ " lg %0,984(%0) \n "
446+ : " =r" (r)::);
447+ if (r != NULL ) {
448+ const char *prod = (int )r[80 ]==4 ? " (MVS LE)" : " " ;
449+ out << " \n Product " << (int )r[80 ] << prod << " Version " << (int )r[81 ] << " Release " << (int )r[82 ] << " Modification " << (int )r[83 ] << std::endl;
450+ }
451+ char hn[256 ];
452+ memset (hn,0 ,sizeof (hn));
453+ gethostname (hn,sizeof (hn));
454+ out << " \n Machine: " << hn << " " << os_info.nodename << " " << os_info.machine << " \n " ;
455+ #else
423456 const char *(*libc_version)();
424457 *(void **)(&libc_version) = dlsym (RTLD_DEFAULT, " gnu_get_libc_version" );
425458 if (libc_version != NULL ) {
426459 out << " (glibc: " << (*libc_version)() << " )" << std::endl;
427460 }
428461 out << " \n Machine: " << os_info.nodename << " " << os_info.machine << " \n " ;
462+ #endif
429463 }
430464#endif
431465}
@@ -694,6 +728,16 @@ void PrintNativeStack(std::ostream& out) {
694728 return ;
695729 }
696730
731+ #ifdef __MVS__
732+ char **res = backtrace_symbols (frames, size);
733+ if (!res)
734+ return ;
735+ for (int i = 0 ; i < size; i++) {
736+ // print traceback symbols and addresses
737+ out << res[i] << std::endl;
738+ }
739+ free (res);
740+ #else
697741 // Print the native frames, omitting the top 3 frames as they are in node-report code
698742 // backtrace_symbols_fd(frames, size, fileno(fp));
699743 for (int i = 2 ; i < size; i++) {
@@ -717,6 +761,7 @@ void PrintNativeStack(std::ostream& out) {
717761 }
718762 out << std::endl;
719763 }
764+ #endif
720765}
721766#endif
722767
@@ -786,7 +831,7 @@ static void PrintResourceUsage(std::ostream& out) {
786831 struct rusage stats;
787832 out << " \n Process total resource usage:" ;
788833 if (getrusage (RUSAGE_SELF, &stats) == 0 ) {
789- #if defined(__APPLE__) || defined(_AIX)
834+ #if defined(__APPLE__) || defined(_AIX) || defined(__MVS__)
790835 snprintf ( buf, sizeof (buf), " %ld.%06d" , stats.ru_utime .tv_sec , stats.ru_utime .tv_usec );
791836 out << " \n User mode CPU: " << buf << " secs" ;
792837 snprintf ( buf, sizeof (buf), " %ld.%06d" , stats.ru_stime .tv_sec , stats.ru_stime .tv_usec );
@@ -801,11 +846,13 @@ static void PrintResourceUsage(std::ostream& out) {
801846 cpu_percentage = (cpu_abs / uptime) * 100.0 ;
802847 out << " \n Average CPU Consumption : " << cpu_percentage << " %" ;
803848 out << " \n Maximum resident set size: " ;
849+ #if !defined(__MVS__)
804850 WriteInteger (out, stats.ru_maxrss * 1024 );
805851 out << " bytes\n Page faults: " << stats.ru_majflt << " (I/O required) "
806852 << stats.ru_minflt << " (no I/O required)" ;
807853 out << " \n Filesystem activity: " << stats.ru_inblock << " reads "
808854 << stats.ru_oublock << " writes" ;
855+ #endif
809856 }
810857#ifdef RUSAGE_THREAD
811858 out << " \n\n Event loop thread resource usage:" ;
@@ -893,16 +940,16 @@ const static struct {
893940 {" core file size (blocks) " , RLIMIT_CORE},
894941 {" data seg size (kbytes) " , RLIMIT_DATA},
895942 {" file size (blocks) " , RLIMIT_FSIZE},
896- #if !(defined(_AIX) || defined(__sun))
943+ #if !(defined(_AIX) || defined(__sun) || defined(__MVS__) )
897944 {" max locked memory (bytes) " , RLIMIT_MEMLOCK},
898945#endif
899- #ifndef __sun
946+ #if !(defined( __sun) || defined(__MVS__))
900947 {" max memory size (kbytes) " , RLIMIT_RSS},
901948#endif
902949 {" open files " , RLIMIT_NOFILE},
903950 {" stack size (bytes) " , RLIMIT_STACK},
904951 {" cpu time (seconds) " , RLIMIT_CPU},
905- #ifndef __sun
952+ #if !(defined( __sun) || defined(__MVS__))
906953 {" max user processes " , RLIMIT_NPROC},
907954#endif
908955 {" virtual memory (kbytes) " , RLIMIT_AS}
@@ -1055,6 +1102,25 @@ static void PrintLoadedLibraries(std::ostream& out, Isolate* isolate) {
10551102 }
10561103 // Release the handle to the process.
10571104 CloseHandle (process_handle);
1105+
1106+ #elif __MVS__
1107+ void *dlcb = 0 ;
1108+ const int max_path = 1024 ;
1109+ char buffer[max_path];
1110+ char filename[max_path];
1111+ char *libpath = __getenv (" LIBPATH" );
1112+ while (dlcb = __dlcb_next (dlcb), dlcb) {
1113+ int len = __dlcb_entry_name (buffer, sizeof (buffer), dlcb);
1114+ void *addr = __dlcb_entry_addr (dlcb);
1115+ if (0 == addr)
1116+ continue ;
1117+ if (buffer[0 ] != ' /' && libpath && __find_file_in_path (filename, sizeof (filename), libpath, buffer) > 0 ) {
1118+ snprintf (buffer + len, sizeof (buffer) - len, " => %s (0x%p)" , filename, addr);
1119+ } else
1120+ snprintf (buffer + len, sizeof (buffer) - len, " (0x%p)" , addr);
1121+ out << " " << buffer << std::endl;
1122+ }
1123+ out << std::flush;
10581124#endif
10591125}
10601126
0 commit comments