| /****************************************************************************** |
| * Copyright (c) 2005 The Regents of the University of California. |
| * This material was produced under U.S. Government contract W-7405-ENG-36 |
| * for Los Alamos National Laboratory, which is operated by the University |
| * of California for the U.S. Department of Energy. The U.S. Government has |
| * rights to use, reproduce, and distribute this software. NEITHER THE |
| * GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR |
| * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified |
| * to produce derivative works, such modified software should be clearly |
| * marked, so as not to confuse it with the version available from LANL. |
| * |
| * Additionally, this program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * LA-CC 04-115 |
| ******************************************************************************/ |
| |
| #include "config.h" |
| #ifndef _AIX |
| #include <getopt.h> |
| #endif |
| #include <stdlib.h> |
| #include <stdarg.h> |
| |
| #include "backend.h" |
| #include "proxy.h" |
| #include "proxy_tcp.h" |
| #include "sdm.h" |
| |
| #define DEFAULT_BACKEND "gdb-mi" |
| #define DEFAULT_PROXY "tcp" |
| |
| extern void master(char *proxy, char *host, int port); |
| extern void server(dbg_backend *dbgr); |
| |
| #define OPT_TYPE_DEBUGGER 0 |
| #define OPT_TYPE_DEBUGGER_PATH 1 |
| #define OPT_TYPE_PROXY 2 |
| #define OPT_TYPE_PORT 3 |
| #define OPT_TYPE_HOST 4 |
| #define OPT_TYPE_MASTER 5 |
| #define OPT_TYPE_SERVER 6 |
| #define OPT_TYPE_DEBUG 7 |
| |
| static int opt_type; |
| |
| #ifndef _AIX |
| static struct option longopts[] = { |
| {"debugger", required_argument, &opt_type, OPT_TYPE_DEBUGGER}, |
| {"debugger_path", required_argument, &opt_type, OPT_TYPE_DEBUGGER_PATH}, |
| {"proxy", required_argument, &opt_type, OPT_TYPE_PROXY}, |
| {"port", required_argument, &opt_type, OPT_TYPE_PORT}, |
| {"host", required_argument, &opt_type, OPT_TYPE_HOST}, |
| {"master", no_argument, &opt_type, OPT_TYPE_MASTER}, |
| {"server", required_argument, &opt_type, OPT_TYPE_SERVER}, |
| #ifdef DEBUG |
| {"debug", optional_argument, &opt_type, OPT_TYPE_DEBUG}, |
| #endif /* DEBUG */ |
| {NULL, 0, NULL, 0} |
| }; |
| #endif |
| |
| #ifdef DEBUG |
| static char * shortopts = "b:e:P:p:h:d:ms:"; |
| #else /* DEBUG */ |
| static char * shortopts = "b:e:P:p:h:ms:"; |
| #endif /* DEBUG */ |
| |
| static int fatal_error = 0; |
| static char *error_str = NULL; |
| |
| void |
| error_msg(char *fmt, ...) |
| { |
| va_list ap; |
| |
| va_start(ap, fmt); |
| vasprintf(&error_str, fmt, ap); |
| va_end(ap); |
| |
| fatal_error = 1; |
| } |
| |
| void |
| print_error_msg() |
| { |
| if (error_str != NULL) { |
| fprintf(stderr, "%s", error_str); |
| fflush(stderr); |
| } |
| } |
| |
| /* |
| * Main entry point for MPI parallel debugger. |
| * |
| * @arg --debugger=type select backend debugger |
| * @arg --debugger_path=path set backend debugger path |
| * @arg --port=port port number to listen on/connect to |
| * @arg --host=host host to connect to |
| * @arg --proxy=proxy_type type of proxy connection to use |
| * @arg --master master process |
| * @arg --server=id server process with rank 'id' |
| */ |
| int |
| main(int argc, char *argv[]) |
| { |
| int ch; |
| int port = PTP_PROXY_TCP_PORT; |
| char * host = NULL; |
| char * debugger_str = DEFAULT_BACKEND; |
| char * proxy_str = DEFAULT_PROXY; |
| char * path = NULL; |
| proxy * p; |
| dbg_backend * d; |
| #ifdef _AIX |
| int n; |
| char * cp; |
| #endif |
| |
| #ifndef _AIX |
| while ((ch = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { |
| if (ch == 0) { |
| switch (opt_type) { |
| case OPT_TYPE_DEBUGGER: |
| debugger_str = optarg; |
| break; |
| case OPT_TYPE_DEBUGGER_PATH: |
| path = optarg; |
| break; |
| case OPT_TYPE_PROXY: |
| proxy_str = optarg; |
| break; |
| case OPT_TYPE_PORT: |
| port = (int)strtol(optarg, NULL, 10); |
| break; |
| case OPT_TYPE_HOST: |
| host = optarg; |
| break; |
| case OPT_TYPE_MASTER: |
| case OPT_TYPE_SERVER: |
| break; |
| #ifdef DEBUG |
| case OPT_TYPE_DEBUG: |
| if (optarg == NULL) |
| debug_level = DEBUG_LEVEL_ALL; |
| else |
| debug_level = (int)strtol(optarg, NULL, 10); |
| break; |
| #endif /* DEBUG */ |
| } |
| } else { |
| fprintf(stderr, |
| "sdm [--debugger=value] [--debugger_path=path]\n" |
| " [--proxy=proxy]\n" |
| " [--host=host_name] [--port=port]\n" |
| " [--master]\n" |
| " [--server=rank]\n" |
| #ifdef DEBUG |
| " [--debug[=level]]\n" |
| #endif /* DEBUG */ |
| ); |
| return 1; |
| } |
| } |
| #else |
| /* |
| * AIX does not support GNU style getopt with long options. |
| * Parse options by string comparison instead. |
| */ |
| n = 1; |
| while (n < argc) { |
| cp = strchr(argv[n], '='); |
| if (cp == NULL) { |
| if (strcmp(argv[n], "--master") == 0 || |
| strncmp(argv[n], "--server", 8) == 0) { |
| /* No action required */ |
| #ifdef DEBUG |
| } else if (strcmp(argv[n], "--debug") == 0) { |
| debug_level = DEBUG_LEVEL_ALL; |
| #endif |
| } |
| else { |
| fprintf(stderr, |
| "sdm [--debugger=value] [--debugger_path=path]\n" |
| " [--proxy=proxy]\n" |
| " [--host=host_name] [--port=port]\n" |
| " [--master]\n" |
| " [--server=rank]\n" |
| #ifdef DEBUG |
| " [--debug[=level]]\n" |
| #endif /* DEBUG */ |
| ); |
| return 1; |
| } |
| } |
| else { |
| *cp = '\0'; |
| if (strncmp(argv[n], "--debugger", 10) == 0) { |
| debugger_str = strdup(cp + 1); |
| } |
| else if (strncmp(argv[n], "--debugger_path", 15) == 0) { |
| path = strdup(cp + 1); |
| } |
| else if (strncmp(argv[n], "--proxy", 7) == 0) { |
| proxy_str = strdup(cp + 1); |
| } |
| else if (strncmp(argv[n], "--port", 6) == 0) { |
| port = (int) strtol(cp + 1, NULL, 10); |
| } |
| else if (strncmp(argv[n], "--host", 6) == 0) { |
| host = strdup(cp + 1); |
| } |
| #ifdef DEBUG |
| else if (strncmp(argv[n], "--debug", 7) == 0) { |
| debug_level = (int) strtol(cp + 1, NULL, 10); |
| } |
| #endif |
| else { |
| fprintf(stderr, |
| "sdm [--debugger=value] [--debugger_path=path]\n" |
| " [--proxy=proxy]\n" |
| " [--host=host_name] [--port=port]\n" |
| " [--master]\n" |
| " [--server=rank]\n" |
| #ifdef DEBUG |
| " [--debug[=level]]\n" |
| #endif /* DEBUG */ |
| ); |
| return 1; |
| } |
| } |
| n = n + 1; |
| } |
| #endif |
| |
| if (find_dbg_backend(debugger_str, &d) < 0) { |
| fprintf(stderr, "No such backend: \"%s\"\n", debugger_str); |
| return 1; |
| } |
| |
| if (path != NULL) { |
| backend_set_path(d, path); |
| } |
| |
| if (find_proxy(proxy_str, &p) < 0) { |
| fprintf(stderr,"No such proxy: \"%s\"\n", proxy_str); |
| return 1; |
| } |
| |
| if (sdm_init(argc, argv) < 0) { |
| DEBUG_PRINTS(DEBUG_LEVEL_STARTUP, "sdm_init failed\n"); |
| return 1; |
| } |
| |
| if (sdm_route_get_id() == SDM_MASTER) { |
| DEBUG_PRINTS(DEBUG_LEVEL_STARTUP, "starting client\n"); |
| master(proxy_str, host, port); |
| } else { |
| DEBUG_PRINTF(DEBUG_LEVEL_STARTUP, "starting task %d\n", sdm_route_get_id()); |
| server(d); |
| } |
| |
| DEBUG_PRINTS(DEBUG_LEVEL_STARTUP, "all finished\n"); |
| |
| sdm_finalize(); |
| |
| return 0; |
| } |