| /******************************************************************************* | |
| * Copyright (c) 2009 Nokia and others. | |
| * All rights reserved. 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 | |
| * | |
| * Contributors: | |
| * Nokia - Initial API and implementation | |
| *******************************************************************************/ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include "ProcessService.h" | |
| #include "WindowsOSDataService.h" | |
| #include "RunControlService.h" | |
| #include "SimpleRegistersService.h" | |
| #include "RegistersService.h" | |
| #include "MemoryService.h" | |
| #include "LoggingService.h" | |
| #include "SettingsService.h" | |
| #include "BreakpointsService.h" | |
| #include "EventClientNotifier.h" | |
| #include "Logger.h" | |
| #include "TCFHeaders.h" | |
| static Protocol * proto; | |
| static ChannelServer * serv; | |
| static TCFBroadcastGroup * bcg; | |
| static long channelCount = 0; | |
| static void channel_server_connecting(Channel * c) { | |
| trace(LOG_PROTOCOL, "channel server connecting"); | |
| send_hello_message(c); | |
| } | |
| static void channel_server_connected(Channel * c) { | |
| channelCount++; | |
| int i; | |
| trace(LOG_PROTOCOL, "channel server connected, peer services:"); | |
| for (i = 0; i < c->peer_service_cnt; i++) { | |
| trace(LOG_PROTOCOL, " %s", c->peer_service_list[i]); | |
| } | |
| } | |
| static void channel_server_receive(Channel * c) { | |
| handle_protocol_message(c); | |
| } | |
| static void channel_server_disconnected(Channel * c) { | |
| trace(LOG_PROTOCOL, "channel server disconnected"); | |
| protocol_release(c->protocol); | |
| channelCount--; | |
| } | |
| static void channel_new_connection(ChannelServer * serv, Channel * c) { | |
| protocol_reference(proto); | |
| c->protocol = proto; | |
| c->connecting = channel_server_connecting; | |
| c->connected = channel_server_connected; | |
| c->receive = channel_server_receive; | |
| c->disconnected = channel_server_disconnected; | |
| channel_set_broadcast_group(c, bcg); | |
| channel_start(c); | |
| } | |
| static void check_for_shutdown(void *x) { | |
| if (channelCount <= 0) { | |
| trace(LOG_PROTOCOL, "check_for_shutdown"); | |
| cancel_event_loop(); | |
| } | |
| post_event_with_delay(check_for_shutdown, NULL, 120 * 1000000); | |
| } | |
| /* | |
| * Central point for cleanup after debug session ends. | |
| */ | |
| void debug_session_ends() { | |
| SettingsService::debugSessionEnds(); | |
| } | |
| // override this so we can actually break on it | |
| _CRTIMP void __cdecl __MINGW_NOTHROW _assert (const char* error, const char* file, int line) | |
| { | |
| char message[256]; | |
| snprintf(message, sizeof(message), | |
| "Fatal error: assertion failed at file=%s, line=%d: %s\n", | |
| file ,line, error); | |
| fputs(message, stderr); | |
| trace(LOG_ALWAYS, message); | |
| exit(3); | |
| } | |
| int main(int argc, char* argv[]) { | |
| #ifdef _DEBUG | |
| static const char* log_name = "C:\\WindowsDebugAgentLog.txt"; | |
| log_mode = LOG_EVENTS | LOG_CHILD | LOG_WAITPID | LOG_CONTEXT | LOG_PROTOCOL | LOG_ASYNCREQ; | |
| open_log_file(log_name); | |
| #endif | |
| try { | |
| // For interim test purpose only: | |
| // Use this unpublished option to turn off BreakpointsService, | |
| // namely use EDC generic breakpoints mechanism. | |
| // | |
| bool installBpService = true; | |
| if (argc > 1 && strcmp(argv[1], "-nobpservice") == 0) | |
| installBpService = false; | |
| static const char * url = "TCP:"; | |
| PeerServer * ps = NULL; | |
| ini_mdep(); | |
| ini_trace(); | |
| ini_asyncreq(); | |
| ini_events_queue(); | |
| bcg = broadcast_group_alloc(); | |
| proto = protocol_alloc(); | |
| LogTrace("Starting up"); | |
| EventClientNotifier::broadcastGroup = bcg; | |
| new ProcessService(proto); | |
| new RunControlService(proto); | |
| new WindowsOSDataService(proto); | |
| new RegistersService(proto); | |
| new MemoryService(proto); | |
| new LoggingService(proto); | |
| new SettingsService(proto); | |
| if (installBpService) | |
| new BreakpointsService(proto); | |
| ps = channel_peer_from_url(url); | |
| peer_server_addprop(ps, loc_strdup("Name"), loc_strdup("Win32 Debug Agent")); | |
| peer_server_addprop(ps, loc_strdup("DebugSupport"), loc_strdup( | |
| "Win32 Debug API")); | |
| LPTSTR lpNameBuffer = NULL; | |
| DWORD lpnSize = 0; | |
| GetComputerName(lpNameBuffer, &lpnSize); | |
| if (lpnSize == 0) // On Win XP this may return zero even if there is a valid name | |
| lpnSize = 1024; | |
| lpNameBuffer = new char[++lpnSize]; | |
| GetComputerName(lpNameBuffer, &lpnSize); | |
| peer_server_addprop(ps, loc_strdup("Description"), loc_strdup(lpNameBuffer)); | |
| delete [] lpNameBuffer; | |
| if (ps == NULL) { | |
| LogTrace("invalid server URL"); | |
| exit(1); | |
| } | |
| serv = channel_server(ps); | |
| if (serv == NULL) { | |
| LogTrace("cannot create TCF server\n"); | |
| exit(1); | |
| } | |
| serv->new_conn = channel_new_connection; | |
| discovery_start(); | |
| #ifdef _DEBUG | |
| #else | |
| post_event_with_delay(check_for_shutdown, NULL, 30 * 1000000); | |
| #endif | |
| run_event_loop(); | |
| } catch (...) { | |
| LogTrace("Exception thrown, caught at main"); | |
| } | |
| return 0; | |
| } |