00001
00002
00003
00004
00005
00006
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include "converse.h"
00010 #include "conv-trace.h"
00011 #include "queueing.h"
00012 #include "conv-ccs.h"
00013 #include <errno.h>
00014
00015 #ifdef _WIN32
00016 # include <io.h>
00017 # define write _write
00018 #endif
00019
00020 CpvCExtern(int, freezeModeFlag);
00021 CpvStaticDeclare(int, continueFlag);
00022 CpvStaticDeclare(int, stepFlag);
00023 CpvCExtern(void *, debugQueue);
00024 CpvDeclare(void*, conditionalQueue);
00025 int conditionalPipe[2] = {0, 0};
00026 int _debugHandlerIdx;
00027
00028 char ** memoryBackup;
00029
00031 extern int _replaySystem;
00032 int _replaySystem = 0;
00033 int _conditionalDelivery = 0;
00034
00035 #undef ConverseDeliver
00036 int ConverseDeliver(int pe) {
00037 return !_replaySystem && (!_conditionalDelivery || pe==CmiMyPe());
00038 }
00039
00040 #if ! CMK_HAS_NTOHL
00041 #ifndef _WIN32
00042 uint32_t ntohl(uint32_t netlong) {
00043 #else
00044 u_long ntohl(u_long netlong) {
00045 #endif
00046 union { uint32_t i; unsigned char c[4]; } uaw;
00047 uaw.i = netlong;
00048 netlong = uaw.c[0]<<24 + uaw.c[1]<<16 + uaw.c[2]<<8 + uaw.c[3];
00049 return netlong;
00050 }
00051 #else
00052 #if defined _WIN32
00053 #include <winsock.h>
00054 #else
00055 #include <arpa/inet.h>
00056 #include <netinet/in.h>
00057 #endif
00058 #endif
00059
00060
00061
00062
00063
00064 #include <string.h>
00065
00066 #include "pup_c.h"
00067
00068 void check_memory_leaks(LeakSearchInfo *info);
00069
00070 CpvDeclare(int, CpdSearchLeaks_Index);
00071 CpvDeclare(int, CpdSearchLeaksDone_Index);
00072 CpvStaticDeclare(CcsDelayedReply, leakSearchDelayedReply);
00073
00074 void CpdSearchLeaksDone(void *msg) {
00075 CmiInt4 ok = 1;
00076 CcsSendDelayedReply(CpvAccess(leakSearchDelayedReply), 4, &ok);
00077 CmiFree(msg);
00078 }
00079
00080 void CpdSearchLeaks(char * msg) {
00081 LeakSearchInfo *info = (LeakSearchInfo *)(msg+CmiMsgHeaderSizeBytes);
00082 if (CmiMyPe() == info->pe || (info->pe == -1 && CmiMyPe() == 0)) {
00083 #if CMK_64BIT
00084 info->begin_data = (char*)(
00085 (((CmiUInt8)ntohl(((int*)&info->begin_data)[0]))<<32) + ntohl(((int*)&info->begin_data)[1]));
00086 info->end_data = (char*)(
00087 (((CmiUInt8)ntohl(((int*)&info->end_data)[0]))<<32) + ntohl(((int*)&info->end_data)[1]));
00088 info->begin_bss = (char*)(
00089 (((CmiUInt8)ntohl(((int*)&info->begin_bss)[0]))<<32) + ntohl(((int*)&info->begin_bss)[1]));
00090 info->end_bss = (char*)(
00091 (((CmiUInt8)ntohl(((int*)&info->end_bss)[0]))<<32) + ntohl(((int*)&info->end_bss)[1]));
00092 #else
00093 info->begin_data = (char*)(ntohl((int)info->begin_data));
00094 info->end_data = (char*)(ntohl((int)info->end_data));
00095 info->begin_bss = (char*)(ntohl((int)info->begin_bss));
00096 info->end_bss = (char*)(ntohl((int)info->end_bss));
00097 #endif
00098 info->quick = ntohl(info->quick);
00099 info->pe = ntohl(info->pe);
00100 CpvAccess(leakSearchDelayedReply) = CcsDelayReply();
00101 if (info->pe == -1) {
00102 CmiSetXHandler(msg, CpvAccess(CpdSearchLeaks_Index));
00103 CmiSetHandler(msg, _debugHandlerIdx);
00104 CmiSyncBroadcast(CmiMsgHeaderSizeBytes+sizeof(LeakSearchInfo), msg);
00105 }
00106 }
00107 check_memory_leaks(info);
00108 if (info->pe == CmiMyPe()) CpdSearchLeaksDone(msg);
00109 else if (info->pe == -1) {
00110 void *reduceMsg = CmiAlloc(0);
00111 CmiSetHandler(reduceMsg, CpvAccess(CpdSearchLeaksDone_Index));
00112 CmiReduce(reduceMsg, CmiMsgHeaderSizeBytes, CmiReduceMergeFn_random);
00113 CmiFree(msg);
00114 }
00115 else CmiAbort("Received allocationTree request for another PE!");
00116 }
00117
00118 void * (*CpdDebugGetAllocationTree)(int *) = NULL;
00119 void (*CpdDebug_pupAllocationPoint)(pup_er p, void *data) = NULL;
00120 void (*CpdDebug_deleteAllocationPoint)(void *ptr) = NULL;
00121 void * (*CpdDebug_MergeAllocationTree)(int *size, void *data, void **remoteData, int numRemote) = NULL;
00122 CpvDeclare(int, CpdDebugCallAllocationTree_Index);
00123 CpvStaticDeclare(CcsDelayedReply, allocationTreeDelayedReply);
00124
00125 static void CpdDebugReturnAllocationTree(void *tree) {
00126 pup_er sizer = pup_new_sizer();
00127 char *buf;
00128 pup_er packer;
00129 int i;
00130 CpdDebug_pupAllocationPoint(sizer, tree);
00131 buf = (char *)malloc(pup_size(sizer));
00132 packer = pup_new_toMem(buf);
00133 CpdDebug_pupAllocationPoint(packer, tree);
00134
00135
00136
00137 CcsSendDelayedReply(CpvAccess(allocationTreeDelayedReply), pup_size(sizer),buf);
00138 pup_destroy(sizer);
00139 pup_destroy(packer);
00140 free(buf);
00141 }
00142
00143 static void CpdDebugCallAllocationTree(char *msg)
00144 {
00145 int numNodes;
00146 int forPE;
00147 void *tree;
00148 if (CpdDebugGetAllocationTree == NULL) {
00149 CmiPrintf("Error> Invoked CpdDebugCalloAllocationTree but no function initialized.\nDid you forget to link in memory charmdebug?\n");
00150 CcsSendReply(0, NULL);
00151 return;
00152 }
00153 sscanf(msg+CmiMsgHeaderSizeBytes, "%d", &forPE);
00154 if (CmiMyPe() == forPE) CpvAccess(allocationTreeDelayedReply) = CcsDelayReply();
00155 if (forPE == -1 && CmiMyPe()==0) {
00156 CpvAccess(allocationTreeDelayedReply) = CcsDelayReply();
00157 CmiSetXHandler(msg, CpvAccess(CpdDebugCallAllocationTree_Index));
00158 CmiSetHandler(msg, _debugHandlerIdx);
00159 CmiSyncBroadcast(CmiMsgHeaderSizeBytes+strlen(msg+CmiMsgHeaderSizeBytes)+1, msg);
00160 }
00161 tree = CpdDebugGetAllocationTree(&numNodes);
00162 if (forPE == CmiMyPe()) CpdDebugReturnAllocationTree(tree);
00163 else if (forPE == -1) CmiReduceStruct(tree, CpdDebug_pupAllocationPoint, CpdDebug_MergeAllocationTree,
00164 CpdDebugReturnAllocationTree, CpdDebug_deleteAllocationPoint);
00165 else CmiAbort("Received allocationTree request for another PE!");
00166 CmiFree(msg);
00167 }
00168
00169 void * (*CpdDebugGetMemStat)(void) = NULL;
00170 void (*CpdDebug_pupMemStat)(pup_er p, void *data) = NULL;
00171 void (*CpdDebug_deleteMemStat)(void *ptr) = NULL;
00172 void * (*CpdDebug_mergeMemStat)(int *size, void *data, void **remoteData, int numRemote) = NULL;
00173 CpvDeclare(int, CpdDebugCallMemStat_Index);
00174 CpvStaticDeclare(CcsDelayedReply, memStatDelayedReply);
00175
00176 static void CpdDebugReturnMemStat(void *stat) {
00177 #if CMK_CCS_AVAILABLE
00178 pup_er sizerNet = pup_new_network_sizer();
00179 pup_er sizer = pup_new_fmt(sizerNet);
00180 char *buf;
00181 pup_er packerNet;
00182 pup_er packer;
00183 int i;
00184 CpdDebug_pupMemStat(sizer, stat);
00185 buf = (char *)malloc(pup_size(sizer));
00186 packerNet = pup_new_network_pack(buf);
00187 packer = pup_new_fmt(packerNet);
00188 CpdDebug_pupMemStat(packer, stat);
00189
00190
00191
00192 CcsSendDelayedReply(CpvAccess(memStatDelayedReply), pup_size(sizer),buf);
00193 pup_destroy(sizerNet);
00194 pup_destroy(sizer);
00195 pup_destroy(packerNet);
00196 pup_destroy(packer);
00197 free(buf);
00198 #endif
00199 }
00200
00201 static void CpdDebugCallMemStat(char *msg) {
00202 int forPE;
00203 void *stat;
00204 if (CpdDebugGetMemStat == NULL) {
00205 CmiPrintf("Error> Invoked CpdDebugCalloMemStat but no function initialized.\nDid you forget to link in memory charmdebug?\n");
00206 CcsSendReply(0, NULL);
00207 return;
00208 }
00209 sscanf(msg+CmiMsgHeaderSizeBytes, "%d", &forPE);
00210 if (CmiMyPe() == forPE) CpvAccess(memStatDelayedReply) = CcsDelayReply();
00211 if (forPE == -1 && CmiMyPe()==0) {
00212 CpvAccess(memStatDelayedReply) = CcsDelayReply();
00213 CmiSetXHandler(msg, CpvAccess(CpdDebugCallMemStat_Index));
00214 CmiSetHandler(msg, _debugHandlerIdx);
00215 CmiSyncBroadcast(CmiMsgHeaderSizeBytes+strlen(msg+CmiMsgHeaderSizeBytes)+1, msg);
00216 }
00217 stat = CpdDebugGetMemStat();
00218 if (forPE == CmiMyPe()) CpdDebugReturnMemStat(stat);
00219 else if (forPE == -1) CmiReduceStruct(stat, CpdDebug_pupMemStat, CpdDebug_mergeMemStat,
00220 CpdDebugReturnMemStat, CpdDebug_deleteMemStat);
00221 else CmiAbort("Received allocationTree request for another PE!");
00222 CmiFree(msg);
00223 }
00224
00225 static void CpdDebugHandlerStatus(char *msg) {
00226 #if ! CMK_NO_SOCKETS
00227 ChMessageInt_t reply[2];
00228 reply[0] = ChMessageInt_new(CmiMyPe());
00229 reply[1] = ChMessageInt_new(CpdIsFrozen() ? 0 : 1);
00230 CcsSendReply(2*sizeof(ChMessageInt_t), reply);
00231 #endif
00232 CmiFree(msg);
00233 }
00234
00235 static void CpdDebugHandlerFreeze(char *msg) {
00236 CpdFreeze();
00237 CmiFree(msg);
00238 }
00239
00240
00241
00242 void CpdNext(void) {
00243
00244 }
00245
00246
00247
00248
00249 void handleDebugMessage(void *msg) {
00250 CmiSetHandler(msg, CmiGetXHandler(msg));
00251 CmiHandleMessage(msg);
00252 }
00253
00254
00255
00256
00257 void CcsServerCheck(void);
00258 extern int _isCcsHandlerIdx(int idx);
00259 int (*CpdIsDebugMessage)(void *);
00260 void * (*CpdGetNextMessage)(CsdSchedulerState_t*);
00261
00262 void CpdFreezeModeScheduler(void)
00263 {
00264 #if CMK_BIGSIM_CHARM
00265 CmiAbort("Cannot run CpdFreezeModeScheduler inside BigSim emulated environment");
00266 #else
00267 #if CMK_CCS_AVAILABLE
00268 void *msg;
00269 void *debugQ=CpvAccess(debugQueue);
00270 CsdSchedulerState_t state;
00271 CsdSchedulerState_new(&state);
00272
00273
00274 while (CpvAccess(freezeModeFlag)) {
00275 #if NODE_0_IS_CONVHOST
00276 if (CmiMyPe()==0) CcsServerCheck();
00277 #endif
00278 msg = CpdGetNextMessage(&state);
00279
00280 if (msg!=NULL) {
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 if (conditionalPipe[1]!=0 && _conditionalDelivery==0) {
00294
00295 int bytes = SIZEFIELD(msg);
00296 if (write(conditionalPipe[1], &bytes, 4) != 4) {
00297 CmiAbort("Writing msg len to child failed!");
00298 }
00299 if (write(conditionalPipe[1], msg, bytes) != bytes) {
00300 CmiAbort("Writing msg data to child failed!");
00301 }
00302 }
00303 if (CpdIsDebugMessage(msg)) {
00304 CmiHandleMessage(msg);
00305 }
00306 else
00307
00308 CdsFifo_Enqueue(debugQ, msg);
00309 } else CmiNotifyIdle();
00310 }
00311
00312
00313 while (!CdsFifo_Empty(debugQ))
00314 {
00315 char *queuedMsg = (char *)CdsFifo_Dequeue(debugQ);
00316 CmiHandleMessage(queuedMsg);
00317 }
00318 #endif
00319 #endif
00320 }
00321
00322 void CpdMemoryMarkClean(char *msg);
00323
00324 void CpdInit(void)
00325 {
00326 #if ! CMK_BIGSIM_CHARM
00327 CpvInitialize(int, freezeModeFlag);
00328 CpvAccess(freezeModeFlag) = 0;
00329
00330 CpvInitialize(void *, debugQueue);
00331 CpvAccess(debugQueue) = CdsFifo_Create();
00332 #endif
00333
00334 CpvInitialize(void *, conditionalQueue);
00335 CpvAccess(conditionalQueue) = CdsFifo_Create();
00336
00337 CcsRegisterHandler("debug/converse/freeze", (CmiHandler)CpdDebugHandlerFreeze);
00338 CcsRegisterHandler("debug/converse/status", (CmiHandler)CpdDebugHandlerStatus);
00339 CcsSetMergeFn("debug/converse/status", CcsMerge_concat);
00340
00341 CcsRegisterHandler("debug/memory/allocationTree", (CmiHandler)CpdDebugCallAllocationTree);
00342 CpvInitialize(int, CpdDebugCallAllocationTree_Index);
00343 CpvAccess(CpdDebugCallAllocationTree_Index) = CmiRegisterHandler((CmiHandler)CpdDebugCallAllocationTree);
00344
00345 CcsRegisterHandler("debug/memory/stat", (CmiHandler)CpdDebugCallMemStat);
00346 CpvInitialize(int, CpdDebugCallMemStat_Index);
00347 CpvAccess(CpdDebugCallMemStat_Index) = CmiRegisterHandler((CmiHandler)CpdDebugCallMemStat);
00348
00349 CcsRegisterHandler("debug/memory/leak",(CmiHandler)CpdSearchLeaks);
00350 CpvInitialize(int, CpdSearchLeaks_Index);
00351 CpvAccess(CpdSearchLeaks_Index) = CmiRegisterHandler((CmiHandler)CpdSearchLeaks);
00352 CpvInitialize(int, CpdSearchLeaksDone_Index);
00353 CpvAccess(CpdSearchLeaksDone_Index) = CmiRegisterHandler((CmiHandler)CpdSearchLeaksDone);
00354
00355 CcsRegisterHandler("debug/memory/mark",(CmiHandler)CpdMemoryMarkClean);
00356 CcsSetMergeFn("debug/memory/mark", CcsMerge_concat);
00357
00358 _debugHandlerIdx = CmiRegisterHandler((CmiHandler)handleDebugMessage);
00359 #if 0
00360 CpdInitializeObjectTable();
00361 CpdInitializeHandlerArray();
00362 CpdInitializeBreakPoints();
00363
00364
00365 msgListCleanup();
00366 msgListCache();
00367 #endif
00368
00369 }
00370
00371
00372 void CpdAborting(const char *message) {
00373 #if CMK_CCS_AVAILABLE
00374 if (CpvAccess(cmiArgDebugFlag)) {
00375 CpdNotify(CPD_ABORT, message);
00376 CpdFreeze();
00377 }
00378 #endif
00379 }