inline THREAD_RETURN eventHandlerWrapper(void *h) { thread_printf("%s[%d]: about to call main() for %s\n", __FILE__, __LINE__, ((EventHandler<EventRecord> *)h)->idstr); ((EventHandler<EventRecord> * )h)->main(); thread_printf("%s[%d]: main returned from %s\n", FILE__, __LINE__, ((EventHandler<EventRecord> *)h)->idstr); DO_THREAD_RETURN; }
bool SignalHandler::handleLwpExit(EventRecord &ev, bool &continueHint) { thread_printf("%s[%d]: welcome to handleLwpExit\n", FILE__, __LINE__); signal_printf("%s[%d]: welcome to handleLwpExit\n", FILE__, __LINE__); process *proc = ev.proc; dyn_lwp *lwp = ev.lwp; dyn_thread *thr = NULL; //Find the exiting thread for (unsigned i=0; i<proc->threads.size(); i++) { if (proc->threads[i]->get_lwp()->get_lwp_id() == lwp->get_lwp_id()) { thr = proc->threads[i]; break; } } if (proc->IndependentLwpControl()) { proc->set_lwp_status(ev.lwp, exited); } ev.lwp->set_dead(); if (!thr) { // DOA thread... continueHint = true; return true; } BPatch::bpatch->registerThreadExit(proc, thr->get_tid(), false); flagBPatchStatusChange(); #if defined(os_windows) if (getExecThreadID() != sg->getThreadID()) { signal_printf("%s[%d][%s]: signalling active process\n", FILE__, __LINE__, getThreadStr(getExecThreadID())); sg->requested_wait_until_active = false; sg->signalActiveProcess(); } #endif #if defined(os_linux) sg->unregisterLWP(lwp->get_lwp_id()); #endif continueHint = true; return true; }
void SignalHandler::main() { // As with the SignalGenerator, we use a custom main to avoid // unlocking in the middle of things; this can screw up our synchronization. addToThreadMap(); startupLock->_Lock(FILE__, __LINE__); signal_printf("%s[%d]: about to do init for %s\n", FILE__, __LINE__, idstr); if (!initialize_event_handler()) { signal_printf("%s[%d]: initialize event handler failed, %s returning\n", FILE__, __LINE__, idstr); _isRunning = false; init_ok = false; removeFromThreadMap(); startupLock->_Broadcast(FILE__, __LINE__); startupLock->_Unlock(FILE__, __LINE__); return; } init_ok = true; signal_printf("%s[%d]: init success for %s\n", FILE__, __LINE__, idstr); _isRunning = true; startupLock->_Broadcast(FILE__, __LINE__); startupLock->_Unlock(FILE__, __LINE__); signal_printf("%s[%d]: before main loop for %s\n", __FILE__, __LINE__, idstr); eventlock->_Lock(FILE__, __LINE__); pdvector<EventRecord> events; while (1) { // TOP signal_printf("%s[%d]: signal handler at top of loop\n", FILE__, __LINE__); assert(eventlock->depth() == 1); if (stop_request) { signal_printf("%s[%d]: exit request (loop top)\n", FILE__, __LINE__); break; } while (!events_to_handle.size()) { waitForEvent(events_to_handle); if (stop_request) { signal_printf("%s[%d]: exit request (post wait)\n", FILE__, __LINE__); break; } } while (events_to_handle.size()) { handleEvent(events_to_handle[0]); if (stop_request) { signal_printf("%s[%d]: exit request (post handle)\n", FILE__, __LINE__); break; } events_to_handle.erase(0,0); } } thread_printf("%s[%d]: removing from thread map\n", FILE__, __LINE__); removeFromThreadMap(); _isRunning = false; if (eventlock->depth() != 1) { fprintf(stderr, "%s[%d]: WARNING: eventlock->depth() is %d, leaving thread %s\n", FILE__, __LINE__, eventlock->depth(),idstr); eventlock->printLockStack(); } eventlock->_Broadcast(FILE__, __LINE__); eventlock->_Unlock(FILE__, __LINE__); thread_printf("%s[%d][%s]: SignalHandler::main exiting\n", FILE__, __LINE__, idstr); }
void EventHandler<T>::main() { addToThreadMap(); thread_printf("%s[%d]: welcome to main() for %s\n", __FILE__, __LINE__, idstr); thread_printf("%s[%d]: new thread id %lu -- %s\n", __FILE__, __LINE__, tid, idstr); startupLock->_Lock(__FILE__, __LINE__); thread_printf("%s[%d]: about to do init for %s\n", __FILE__, __LINE__, idstr); if (!initialize_event_handler()) { _isRunning = false; init_ok = false; removeFromThreadMap(); startupLock->_Broadcast(__FILE__, __LINE__); startupLock->_Unlock(__FILE__, __LINE__); return; } init_ok = true; thread_printf("%s[%d]: init success for %s\n", __FILE__, __LINE__, idstr); _isRunning = true; startupLock->_Broadcast(__FILE__, __LINE__); startupLock->_Unlock(__FILE__, __LINE__); T ev; thread_printf("%s[%d]: before main loop for %s\n", __FILE__, __LINE__, idstr); while (1) { if (!this->waitNextEvent(ev)) { fprintf(stderr, "%s[%d][%s]: waitNextEvent failed \n", __FILE__, __LINE__,getThreadStr(getExecThreadID())); if (!stop_request) continue; } if (stop_request) { thread_printf("%s[%d]: thread terminating at stop request\n", __FILE__, __LINE__); break; } if (!handleEvent(ev)) { fprintf(stderr, "%s[%d][%s]: handleEvent() failed\n", __FILE__, __LINE__, getThreadStr(getExecThreadID())); } if (stop_request) break; } global_mutex->_Lock(FILE__, __LINE__); removeFromThreadMap(); _isRunning = false; if (global_mutex->depth() != 1) { fprintf(stderr, "%s[%d]: WARNING: global_mutex->depth() is %d, leaving thread %s\n", FILE__, __LINE__, global_mutex->depth(),idstr); global_mutex->printLockStack(); } assert(global_mutex->depth() == 1); global_mutex->_Broadcast(FILE__, __LINE__); global_mutex->_Unlock(FILE__, __LINE__); thread_printf("%s[%d][%s]: InternalThread::main exiting\n", FILE__, __LINE__, idstr); }
bool InternalThread::createThread() { thread_printf("%s[%d] welcome to createThread(%s)\n", __FILE__, __LINE__, idstr); if (isRunning()) { fprintf(stderr, "%s[%d]: WARNING: cannot create thread '%s'which is already running\n", __FILE__, __LINE__, idstr); return true; } startupLock = new eventLock(); startupLock->_Lock(__FILE__, __LINE__); #if defined(os_windows) handler_thread = _beginthread(eventHandlerWrapper, 0, (void *) this); if (-1L == handler_thread) { bperr("%s[%d]: _beginthread(...) failed\n", __FILE__, __LINE__); return false; } #else // Unixes int err = 0; pthread_attr_t handler_thread_attr; err = pthread_attr_init(&handler_thread_attr); if (err) { bperr("%s[%d]: could not init async handler thread attributes: %s, %d\n", __FILE__, __LINE__, strerror(err), err); return false; } err = pthread_attr_setdetachstate(&handler_thread_attr, PTHREAD_CREATE_DETACHED); if (err) { bperr("%s[%d]: could not set async handler thread attrixibcutes: %s, %d\n", __FILE__, __LINE__, strerror(err), err); return false; } try { err = pthread_create(&handler_thread, &handler_thread_attr, &eventHandlerWrapper, (void *) this); if (err) { bperr("%s[%d]: could not start async handler thread: %s, %d\n", __FILE__, __LINE__, strerror(err), err); fprintf(stderr,"%s[%d]: could not start async handler thread: %s, %d\n", __FILE__, __LINE__, strerror(err), err); return false; } } catch(...) { assert(0); } err = pthread_attr_destroy(&handler_thread_attr); if (err) { bperr("%s[%d]: could not destroy async handler attr: %s, %d\n", __FILE__, __LINE__, strerror(err), err); return false; } #endif while (!_isRunning && (init_ok)) { thread_printf("%s[%d]: createThread (%s) waiting for thread main to start\n", __FILE__, __LINE__, idstr); startupLock->_WaitForSignal(__FILE__, __LINE__); thread_printf("%s[%d]: createThread (%s) got signal\n", __FILE__, __LINE__, idstr); } startupLock->_Unlock(__FILE__, __LINE__); thread_printf("%s[%d]: createThread returning %d\n", FILE__, __LINE__, init_ok); if (!init_ok) { return false; } return true; }
/*----------------------------------------------------------------------------*/ void DumpPacket(mtcp_manager_t mtcp, char *buf, int len, char *step, int ifindex) { struct ethhdr *ethh; struct iphdr *iph; struct udphdr *udph; struct tcphdr *tcph; uint8_t *t; if (ifindex >= 0) thread_printf(mtcp, mtcp->log_fp, "%s %d %u", step, ifindex, mtcp->cur_ts); else thread_printf(mtcp, mtcp->log_fp, "%s ? %u", step, mtcp->cur_ts); ethh = (struct ethhdr *)buf; if (ntohs(ethh->h_proto) != ETH_P_IP) { thread_printf(mtcp, mtcp->log_fp, "%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X ", ethh->h_source[0], ethh->h_source[1], ethh->h_source[2], ethh->h_source[3], ethh->h_source[4], ethh->h_source[5], ethh->h_dest[0], ethh->h_dest[1], ethh->h_dest[2], ethh->h_dest[3], ethh->h_dest[4], ethh->h_dest[5]); thread_printf(mtcp, mtcp->log_fp, "protocol %04hx ", ntohs(ethh->h_proto)); goto done; } thread_printf(mtcp, mtcp->log_fp, " "); iph = (struct iphdr *)(ethh + 1); udph = (struct udphdr *)((uint32_t *)iph + iph->ihl); tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl); t = (uint8_t *)&iph->saddr; thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]); if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->source)); thread_printf(mtcp, mtcp->log_fp, " -> "); t = (uint8_t *)&iph->daddr; thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]); if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->dest)); thread_printf(mtcp, mtcp->log_fp, " IP_ID=%d", ntohs(iph->id)); thread_printf(mtcp, mtcp->log_fp, " TTL=%d ", iph->ttl); if (ip_fast_csum(iph, iph->ihl)) { __sum16 org_csum, correct_csum; org_csum = iph->check; iph->check = 0; correct_csum = ip_fast_csum(iph, iph->ihl); thread_printf(mtcp, mtcp->log_fp, "(bad checksum %04x should be %04x) ", ntohs(org_csum), ntohs(correct_csum)); iph->check = org_csum; } switch (iph->protocol) { case IPPROTO_TCP: thread_printf(mtcp, mtcp->log_fp, "TCP "); if (tcph->syn) thread_printf(mtcp, mtcp->log_fp, "S "); if (tcph->fin) thread_printf(mtcp, mtcp->log_fp, "F "); if (tcph->ack) thread_printf(mtcp, mtcp->log_fp, "A "); if (tcph->rst) thread_printf(mtcp, mtcp->log_fp, "R "); thread_printf(mtcp, mtcp->log_fp, "seq %u ", ntohl(tcph->seq)); if (tcph->ack) thread_printf(mtcp, mtcp->log_fp, "ack %u ", ntohl(tcph->ack_seq)); thread_printf(mtcp, mtcp->log_fp, "WDW=%u ", ntohs(tcph->window)); break; case IPPROTO_UDP: thread_printf(mtcp, mtcp->log_fp, "UDP "); break; default: thread_printf(mtcp, mtcp->log_fp, "protocol %d ", iph->protocol); goto done; } done: thread_printf(mtcp, mtcp->log_fp, "len=%d\n", len); }
/*----------------------------------------------------------------------------*/ void DumpIPPacket(mtcp_manager_t mtcp, const struct iphdr *iph, int len) { struct udphdr *udph; struct tcphdr *tcph; uint8_t *t; udph = (struct udphdr *)((uint32_t *)iph + iph->ihl); tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl); t = (uint8_t *)&iph->saddr; thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]); if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->source)); thread_printf(mtcp, mtcp->log_fp, " -> "); t = (uint8_t *)&iph->daddr; thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]); if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->dest)); thread_printf(mtcp, mtcp->log_fp, " IP_ID=%d", ntohs(iph->id)); thread_printf(mtcp, mtcp->log_fp, " TTL=%d ", iph->ttl); if (ip_fast_csum(iph, iph->ihl)) { thread_printf(mtcp, mtcp->log_fp, "(bad checksum) "); } switch (iph->protocol) { case IPPROTO_TCP: thread_printf(mtcp, mtcp->log_fp, "TCP "); if (tcph->syn) thread_printf(mtcp, mtcp->log_fp, "S "); if (tcph->fin) thread_printf(mtcp, mtcp->log_fp, "F "); if (tcph->ack) thread_printf(mtcp, mtcp->log_fp, "A "); if (tcph->rst) thread_printf(mtcp, mtcp->log_fp, "R "); thread_printf(mtcp, mtcp->log_fp, "seq %u ", ntohl(tcph->seq)); if (tcph->ack) thread_printf(mtcp, mtcp->log_fp, "ack %u ", ntohl(tcph->ack_seq)); thread_printf(mtcp, mtcp->log_fp, "WDW=%u ", ntohs(tcph->window)); break; case IPPROTO_UDP: thread_printf(mtcp, mtcp->log_fp, "UDP "); break; default: thread_printf(mtcp, mtcp->log_fp, "protocol %d ", iph->protocol); goto done; } done: thread_printf(mtcp, mtcp->log_fp, "len=%d\n", len); }
/*----------------------------------------------------------------------------*/ int FlushWriteBuffer(struct mtcp_thread_context* ctx, int ifidx) { int ret = 0; struct ps_chunk* w_chunk = ctx->w_chunk; mtcp_manager_t mtcp = ctx->mtcp_manager; int i; int drop = 0; assert(ctx != NULL); assert(w_chunk != NULL); if (w_chunk[ifidx].cnt > 0) { STAT_COUNT(mtcp->runstat.rounds_tx_try); ret = ps_send_chunk(ctx->handle, &w_chunk[ifidx]); drop = ctx->w_chunk[ifidx].cnt - ret; if (ret < 0) { TRACE_ERROR("ps_send_chunk failed to send chunks, %d:%d\n", ifidx, w_chunk[ifidx].cnt); return ret; } else { #ifdef NETSTAT mtcp->nstat.tx_packets[ifidx] += ret; #endif /* NETSTAT */ for (i = 0; i < ret; i++) { #ifdef PKTDUMP DumpPacket(mtcp, w_chunk[ifidx].buf + w_chunk[ifidx].info[i].offset, w_chunk[ifidx].info[i].len, "OUT", ifidx); #endif /* PKTDUMP */ #ifdef NETSTAT mtcp->nstat.tx_bytes[ifidx] += w_chunk[ifidx].info[i].len + 24; #endif /* NETSTAT */ } #ifdef NETSTAT if (ret != w_chunk[ifidx].cnt) { mtcp->nstat.tx_drops[ifidx] += (w_chunk[ifidx].cnt - ret); } #endif /* NETSTAT */ if (ret == 0) { return ret; } } #ifdef PKTDUMP thread_printf(mtcp, mtcp->log_fp, "sent chunks, ret: %d (tries: %d)\n", ret, w_chunk[ifidx].cnt); thread_printf(mtcp, mtcp->log_fp, "======================================" "======================================================" "====================\n\n"); #endif /* PKTDUMP */ if (drop > 0) { ctx->w_chunk[ifidx].cnt = drop; for (i = 0; i < drop; i++) { ctx->w_chunk[ifidx].info[i].len = ctx->w_chunk[ifidx].info[ret + i].len; ctx->w_chunk[ifidx].info[i].offset = ctx->w_chunk[ifidx].info[ret + i].offset; } ctx->w_off[ifidx] = ctx->w_chunk[ifidx].info[drop - 1].offset + (ctx->w_chunk[ifidx].info[drop - 1].len + 63) / 64 * 64; ctx->w_cur_idx[ifidx] += ret; } else { ctx->w_chunk[ifidx].cnt = 0; ctx->w_off[ifidx] = 0; ctx->w_cur_idx[ifidx] = 0; } } return ret; }