/* * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2011 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2006-2013 Los Alamos National Security, LLC. * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ * */ #include #include #include #include #include int main(int argc, char **argv) { pmix_status_t rc; pmix_proc_t myproc; pmix_info_t *info; pmix_app_t *app; size_t ninfo, napps; bool failed = false; /* require that the user specify the job we are to launch * a debugger against */ if (2 < argc) { fprintf(stderr, "usage: debug \n"); exit(1); } /* init us */ if (PMIX_SUCCESS != (rc = PMIx_tool_init(&myproc, NULL, 0))) { fprintf(stderr, "PMIx_tool_init failed: %d\n", rc); exit(rc); } fprintf(stderr, "Tool ns %s rank %d: Running\n", myproc.nspace, myproc.rank); /* query the active nspaces so we can verify that the * specified one exists */ ninfo = 1; PMIX_INFO_CREATE(info, ninfo); (void)strncpy(info[0].key, PMIX_QUERY_NAMESPACES, PMIX_MAX_KEYLEN); if (PMIX_SUCCESS != (rc = PMIx_Query_info(info, ninfo))) { fprintf(stderr, "Client ns %s rank %d: PMIx_Query_info failed: %d\n", myproc.nspace, myproc.rank, rc); failed = true; goto done; } /* the query should have returned a comma-delimited list of nspaces */ if (PMIX_STRING != info[0].type) { fprintf(stderr, "Query returned incorrect data type: %d\n", info[0].type); failed = true; goto done; } if (NULL == info[0].data.string) { fprintf(stderr, "Query returned no active nspaces\n"); failed = true; goto done; } /* split the returned string and look for the given nspace */ PMIX_INFO_FREE(info, ninfo); /* get the proctable for this nspace */ ninfo = 1; PMIX_INFO_CREATE(info, ninfo); (void)strncpy(info[0].key, PMIX_QUERY_PROC_TABLE, PMIX_MAX_KEYLEN); (void)strncpy(info[0].qualifier, nspace, PMIX_MAX_KEYLEN); if (PMIX_SUCCESS != (rc = PMIx_Query_info(info, ninfo))) { fprintf(stderr, "Client ns %s rank %d: PMIx_Query_info failed: %d\n", myproc.nspace, myproc.rank, rc); failed = true; goto done; } /* the query should have returned a data_array */ if (PMIX_DATA_ARRAY != info[0].type) { fprintf(stderr, "Query returned incorrect data type: %d\n", info[0].type); failed = true; goto done; } if (NULL == info[0].data.darray.array) { fprintf(stderr, "Query returned no proctable info\n"); failed = true; goto done; } /* the data array consists of a struct: * size_t size; * void* array; * * In this case, the array is composed of pmix_proc_info_t structs: * pmix_proc_t proc; // contains the nspace,rank of this proc * char* hostname; * char* executable_name; * pid_t pid; * int exit_code; * pmix_proc_state_t state; */ /* this is where a debugger tool would process the proctable to * create whatever blob it needs to provide to its daemons */ PMIX_INFO_FREE(info, ninfo); /* setup the debugger daemon spawn request */ napps = 1; PMIX_APP_CREATE(app, napps); /* setup the name of the daemon executable to launch */ app[0].cmd = strdup("debuggerdaemon"); app[0].argc = 1; app[0].argv = (char**)malloc(2*sizeof(char*)); app[0].argv[0] = strdup("debuggerdaemon"); app[0].argv[1] = NULL; /* provide directives so the daemons go where we want, and * let the RM know these are debugger daemons */ ninfo = 2; PMIX_INFO_CREATE(app[0].info, ninfo); PMIX_INFO_LOAD(&app[0].info[0], PMIX_MAPBY, "ppr:1:node", PMIX_STRING); // instruct the RM to launch one copy of the executable on each node PMIX_INFO_LOAD(&app[0].info[1], PMIX_DEBUGGER_DAEMONS, true, PMIX_BOOL); // these are debugger daemons /* spawn the daemons */ PMIx_Spawn(NULL, 0, app, napps, dspace); /* cleanup */ PMIX_APP_FREE(app, napps); /* this iw where a debugger tool would wait until the debug operation is complete */ done: /* finalize us */ fprintf(stderr, "Client ns %s rank %d: Finalizing\n", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc); } else { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank); } fprintf(stderr, "Test %s\n", failed ? "FAILED" : "SUCCEEDED"); fflush(stderr); return(rc); }