// perform an action (func) on all debuggers int for_all_debuggers(debmod_visitor_t &v) { int code = 0; qmutex_lock(g_lock); { rpc_server_list_t::iterator it; for ( it=clients_list.begin(); it != clients_list.end(); ++it ) { code = v.visit(it->first->get_debugger_instance()); if ( code != 0 ) break; } } qmutex_unlock(g_lock); return code; }
//-------------------------------------------------------------------------- static void NT_CDECL shutdown_gracefully(int signum) { qeprintf("got signal #%d\n", signum); #ifdef __SINGLE_THREADED_SERVER__ if ( g_global_server != NULL ) { debmod_t *d = g_global_server->get_debugger_instance(); if ( d != NULL ) d->dbg_exit_process(); g_global_server->term_irs(); } #else qmutex_lock(g_lock); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { rpc_server_t *server = it->first; qthread_t thr = it->second; // free thread if ( thr != NULL ) qthread_free(thr); if ( server == NULL || server->irs == NULL ) continue; debmod_t *d = server->get_debugger_instance(); if ( d != NULL ) d->dbg_exit_process(); // kill the process instead of letting it run in wild server->term_irs(); } clients_list.clear(); qmutex_unlock(g_lock); qmutex_free(g_lock); #endif if ( listen_socket != INVALID_SOCKET ) closesocket(listen_socket); term_subsystem(); _exit(1); }
//-------------------------------------------------------------------------- static void NT_CDECL shutdown_gracefully(int signum) { if ( signum == SIGINT && ignore_sigint ) { ignore_sigint = false; return; } #if defined(__NT__) || defined(__ARM__) // strsignal() is not available qeprintf("got signal #%d, terminating\n", signum); #else qeprintf("%s: terminating the server\n", strsignal(signum)); #endif srv_lock_begin(); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { rpc_server_t *server = it->first; #ifndef __SINGLE_THREADED_SERVER__ qthread_t thr = it->second; // free thread if ( thr != NULL ) qthread_free(thr); #endif if ( server == NULL || server->irs == NULL ) continue; debmod_t *d = server->get_debugger_instance(); if ( d != NULL ) d->dbg_exit_process(); // kill the process instead of letting it run in wild server->term_irs(); } clients_list.clear(); srv_lock_end(); srv_lock_free(); if ( listen_socket != INVALID_SOCKET ) closesocket(listen_socket); term_subsystem(); _exit(1); }
//-------------------------------------------------------------------------- static void handle_single_session(rpc_server_t *server) { lprintf("=========================================================\n" "Accepting incoming connection...\n"); qstring open = prepare_rpc_packet(RPC_OPEN); append_long(open, IDD_INTERFACE_VERSION); append_long(open, DEBUGGER_ID); append_long(open, sizeof(ea_t)); rpc_packet_t *rp = server->process_request(open, PRF_LOGIN|PRF_DONT_POLL); if ( rp == NULL ) { lprintf("Could not establish the connection\n"); delete server; return; } // Answer is beyond the rpc_packet_t buffer const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; bool send_response = true; bool ok = extract_long(&answer, end); if ( !ok ) { lprintf("Incompatible IDA Pro version\n"); send_response = false; } else if ( server_password != NULL ) { char *pass = extract_str(&answer, end); if ( strcmp(pass, server_password) != '\0' ) { lprintf("Bad password\n"); ok = false; } } qfree(rp); if ( send_response ) { server->poll_debug_events = false; server->has_pending_event = false; open = prepare_rpc_packet(RPC_OK); append_long(open, ok); server->send_request(open); if ( ok ) { qstring cmd; rpc_packet_t *packet = server->process_request(cmd, PRF_POLL); if ( packet != NULL ) qfree(packet); } } server->network_error_code = 0; lprintf("Closing incoming connection...\n"); server->term_irs(); #ifndef __SINGLE_THREADED_SERVER__ // Remove the session from the list qmutex_lock(g_lock); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { if ( it->first != server ) continue; // free the thread resources qthread_free(it->second); // remove client from the list clients_list.erase(it); break; } qmutex_unlock(g_lock); #endif // Free the debug session delete server; }
//-------------------------------------------------------------------------- static void handle_single_session(rpc_server_t *server) { static int s_sess_id = 1; int sid = s_sess_id++; char peername[MAXSTR]; if ( !irs_peername(server->irs, peername, sizeof(peername), false) ) qstrncpy(peername, "(unknown)", sizeof(peername)); lprintf("=========================================================\n" "[%d] Accepting connection from %s...\n", sid, peername); bytevec_t req = prepare_rpc_packet(RPC_OPEN); append_dd(req, IDD_INTERFACE_VERSION); append_dd(req, DEBUGGER_ID); append_dd(req, sizeof(ea_t)); rpc_packet_t *rp = server->process_request(req, true); bool handle_request = true; bool send_response = true; bool ok; if ( rp == NULL ) { lprintf("[%d] Could not establish the connection\n", sid); handle_request = false; send_response = false; } if ( handle_request ) { // Answer is beyond the rpc_packet_t buffer const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; ok = extract_long(&answer, end) != 0; if ( !ok ) { lprintf("[%d] Incompatible IDA version\n", sid); send_response = false; } else if ( server_password != NULL ) { char *pass = extract_str(&answer, end); if ( strcmp(pass, server_password) != '\0' ) { lprintf("[%d] Bad password\n", sid); ok = false; } } qfree(rp); } if ( send_response ) { req = prepare_rpc_packet(RPC_OK); append_dd(req, ok); server->send_request(req); if ( ok ) { // the main loop: handle client requests until it drops the connection // or sends us RPC_OK (see rpc_debmod_t::close_remote) bytevec_t empty; rpc_packet_t *packet = server->process_request(empty); if ( packet != NULL ) qfree(packet); } } server->network_error_code = 0; lprintf("[%d] Closing connection from %s...\n", sid, peername); bool preserve_server = keep_broken_connections && server->get_broken_connection(); if ( !preserve_server ) { // Terminate dedicated debugger instance. server->get_debugger_instance()->dbg_term(); server->term_irs(); } else { server->term_irs(); lprintf("[%d] Debugged session entered into sleeping mode\n", sid); server->prepare_broken_connection(); } if ( !preserve_server ) { // Remove the session from the list srv_lock_begin(); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { if ( it->first != server ) continue; #ifndef __SINGLE_THREADED_SERVER__ // free the thread resources qthread_free(it->second); #endif // remove client from the list clients_list.erase(it); break; } srv_lock_end(); // Free the debug session delete server; } }