m_jvmdebug.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       m_jvmdebug.cc
00003 ///             Mode class for the JVMDebug mode
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008     Copyright (C) 2008-2009, Nicolas VIVIEN
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019     See the GNU General Public License in the COPYING file at the
00020     root directory of this project for more details.
00021 */
00022 
00023 #include "m_jvmdebug.h"
00024 #include "data.h"
00025 #include "protocol.h"
00026 #include "protostructs.h"
00027 #include "packet.h"
00028 #include "endian.h"
00029 #include "error.h"
00030 #include "usbwrap.h"
00031 #include "controller.h"
00032 #include "cod.h"
00033 #include <stdexcept>
00034 #include <sstream>
00035 #include <iomanip>
00036 #include <vector>
00037 #include <string.h>
00038 #include <time.h>
00039 #include <stdio.h>
00040 #include "ios_state.h"
00041 
00042 #include "debug.h"
00043 
00044 using namespace std;
00045 using namespace Barry::Protocol;
00046 
00047 namespace Barry {
00048 
00049 ///////////////////////////////////////////////////////////////////////////////
00050 // JDModulesList class
00051 
00052 void JVMModulesList::Parse(const Data &entry_packet)
00053 {
00054         uint16_t count = 0;
00055 
00056         size_t size = entry_packet.GetSize();
00057 
00058         while (count < size) {
00059                 uint16_t len = 0;
00060 
00061                 const unsigned char *ptr = (entry_packet.GetData() + count);
00062                 Protocol::JVMModulesEntry *e = (Protocol::JVMModulesEntry *) ptr;
00063 
00064                 len = SB_JVMMODULES_ENTRY_HEADER_SIZE + be_btohs(e->sizename);
00065                 if( (count + len) > size )
00066                         break;
00067 
00068                 JVMModulesEntry entry;
00069 
00070                 entry.Id = be_btohl(e->id);
00071                 entry.UniqueID = be_btohl(e->uniqueId);
00072                 (entry.Name).assign((char *) (ptr + SB_JVMMODULES_ENTRY_HEADER_SIZE), be_btohs(e->sizename));
00073 
00074                 push_back(entry);
00075 
00076                 count += len;
00077         }
00078 }
00079 
00080 
00081 void JVMModulesList::Dump(std::ostream &os) const
00082 {
00083         ios_format_state state(os);
00084 
00085         const_iterator i = begin(), e = end();
00086 
00087         os << "     ID     " << "|";
00088         os << "  UniqueID  " << "|";
00089         os << " Module Name" << endl;
00090 
00091         os << "------------+";
00092         os << "------------+";
00093         os << "-------------";
00094         os << endl;
00095 
00096         for( ; i != e; ++i ) {
00097                 (*i).Dump(os);
00098         }
00099 }
00100 
00101 
00102 ///////////////////////////////////////////////////////////////////////////////
00103 // JVMModulesEntry class
00104 
00105 void JVMModulesEntry::Dump(std::ostream &os) const
00106 {
00107         ios_format_state state(os);
00108 
00109         os << " 0x" << setfill('0') << setw(8) << hex << Id << " |";
00110         os << " 0x" << setfill('0') << setw(8) << hex << UniqueID << " |";
00111         os << " " << Name << endl;
00112 }
00113 
00114 
00115 ///////////////////////////////////////////////////////////////////////////////
00116 // JVMThreadsList class
00117 
00118 void JVMThreadsList::Parse(const Data &entry_packet)
00119 {
00120         uint16_t count = 0;
00121 
00122         size_t size = entry_packet.GetSize();
00123 
00124         while (count < size) {
00125                 uint16_t len = 0;
00126 
00127                 const unsigned char *ptr = (entry_packet.GetData() + count);
00128                 uint32_t *e = (uint32_t *) ptr;
00129 
00130                 len = sizeof(uint32_t);
00131                 if( (count + len) > size )
00132                         break;
00133 
00134                 JVMThreadsEntry entry;
00135 
00136                 entry.Id = be_btohl(*e);
00137 
00138                 push_back(entry);
00139 
00140                 count += len;
00141         }
00142 }
00143 
00144 
00145 void JVMThreadsList::Dump(std::ostream &os) const
00146 {
00147         ios_format_state state(os);
00148 
00149         const_iterator i = begin(), e = end();
00150 
00151         os << "  Thread  " << "|";
00152         os << "  Address   " << "|";
00153         os << " Byte " << "|";
00154         os << " Unknown01  " << "|";
00155         os << " Unknown02  " << "|";
00156         os << " Unknown03  " << "|";
00157         os << " Unknown04  " << "|";
00158         os << " Unknown05  " << "|";
00159         os << " Unknown06  " << "|";
00160 
00161         os << "------------+";
00162         os << "------------+";
00163         os << "------+";
00164         os << "------------+";
00165         os << "------------+";
00166         os << "------------+";
00167         os << "------------+";
00168         os << "------------+";
00169         os << "-------------";
00170         os << endl;
00171 
00172         for(int k=0 ; i != e; ++i, k++ ) {
00173                 (*i).Dump(os, k);
00174         }
00175 }
00176 
00177 
00178 void JVMThreadsEntry::Dump(std::ostream &os, int num) const
00179 {
00180         ios_format_state state(os);
00181 
00182         os << " " << setfill(' ') << setw(8) << dec << num << " |";
00183         os << " 0x" << setfill('0') << setw(8) << hex << (Id) << " |";
00184         os << " 0x" << setfill('0') << setw(2) << hex << (Byte) << " |";
00185         os << " 0x" << setfill('0') << setw(8) << hex << (Address) << " |";
00186         os << " 0x" << setfill('0') << setw(8) << hex << (Unknown01) << " |";
00187         os << " 0x" << setfill('0') << setw(8) << hex << (Unknown02) << " |";
00188         os << " 0x" << setfill('0') << setw(8) << hex << (Unknown03) << " |";
00189         os << " 0x" << setfill('0') << setw(8) << hex << (Unknown04) << " |";
00190         os << " 0x" << setfill('0') << setw(8) << hex << (Unknown05) << " |";
00191         os << " 0x" << setfill('0') << setw(8) << hex << (Unknown06) << endl;
00192 }
00193 
00194 
00195 namespace Mode {
00196 
00197 ///////////////////////////////////////////////////////////////////////////////
00198 // JVMDebug Mode class
00199 
00200 JVMDebug::JVMDebug(Controller &con)
00201         : Mode(con, Controller::JVMDebug)
00202         , m_Attached(false)
00203 {
00204 }
00205 
00206 JVMDebug::~JVMDebug()
00207 {
00208         if( m_Attached )
00209                 Detach();
00210 }
00211 
00212 ///////////////////////////////////////////////////////////////////////////////
00213 // protected members
00214 
00215 
00216 ///////////////////////////////////////////////////////////////////////////////
00217 // public API
00218 
00219 void JVMDebug::OnOpen()
00220 {
00221 }
00222 
00223 // FIXME - is this necessary?  and if it is, wouldn't it be better
00224 // in the m_jvmdebug mode class?  I'm not convinced that applications
00225 // should have to bother with socket-level details.
00226 void JVMDebug::Close()
00227 {
00228         if( m_ModeSocket ) {
00229                 m_socket->Close();
00230                 m_socket.reset();
00231                 m_ModeSocket = 0;
00232         }
00233 }
00234 
00235 //
00236 // Attach
00237 //
00238 /// These commands are sent to prepare the debug communication.
00239 /// Must be called at the start of a JVMDebug session.
00240 ///
00241 void JVMDebug::Attach()
00242 {
00243 }
00244 
00245 //
00246 // Detach
00247 //
00248 /// Must be called at the end of a JVMDebug session.  The JVM_GOODBYE
00249 /// command is sent to the device.
00250 ///
00251 void JVMDebug::Detach()
00252 {
00253 }
00254 
00255 
00256 void JVMDebug::ThrowJVMError(const std::string &msg, uint8_t cmd)
00257 {
00258         std::ostringstream oss;
00259         oss << msg << ": unexpected packet command code: 0x"
00260                 << std::hex << (unsigned int) cmd;
00261         throw Error(oss.str());
00262 }
00263 
00264 
00265 //
00266 // Unknown 01 ???
00267 //
00268 void JVMDebug::Unknown01()
00269 {
00270         uint16_t expect = 0;
00271 
00272         Data command(-1, 8), response;
00273         JVMPacket packet(command, response);
00274 
00275         // Send the command packet
00276         packet.Unknown01();
00277         m_socket->Packet(packet);
00278         expect = packet.Size();
00279 
00280         if (expect == 0)
00281                 return;
00282 
00283         // Read the data stream
00284         m_socket->Receive(response);
00285 
00286         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00287 
00288         // Check the size read into the previous packet
00289         if( expect != bytereceived ) {
00290                 ThrowJVMError("JVMDebug::Attach expect", expect);
00291         }
00292 }
00293 
00294 
00295 //
00296 // Unknown 02 ???
00297 //
00298 void JVMDebug::Unknown02()
00299 {
00300         uint16_t expect = 0;
00301 
00302         Data command(-1, 8), response;
00303         JVMPacket packet(command, response);
00304 
00305         // Send the command packet
00306         packet.Unknown02();
00307         m_socket->Packet(packet);
00308         expect = packet.Size();
00309 
00310         if (expect == 0)
00311                 return;
00312 
00313         // Read the data stream
00314         m_socket->Receive(response);
00315 
00316         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00317 
00318         // Check the size read into the previous packet
00319         if( expect != bytereceived ) {
00320                 ThrowJVMError("JVMDebug::Attach expect", expect);
00321         }
00322 }
00323 
00324 
00325 //
00326 // Unknown 03 ???
00327 //
00328 void JVMDebug::Unknown03()
00329 {
00330         uint16_t expect = 0;
00331 
00332         Data command(-1, 8), response;
00333         JVMPacket packet(command, response);
00334 
00335         // Send the command packet
00336         packet.Unknown03();
00337         m_socket->Packet(packet);
00338         expect = packet.Size();
00339 
00340         if (expect == 0)
00341                 return;
00342 
00343         // Read the data stream
00344         m_socket->Receive(response);
00345 
00346         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00347 
00348         // Check the size read into the previous packet
00349         if( expect != bytereceived ) {
00350                 ThrowJVMError("JVMDebug::Attach expect", expect);
00351         }
00352 }
00353 
00354 
00355 //
00356 // Unknown 04 ???
00357 //
00358 void JVMDebug::Unknown04()
00359 {
00360         uint16_t expect = 0;
00361 
00362         Data command(-1, 8), response;
00363         JVMPacket packet(command, response);
00364 
00365         // Send the command packet
00366         packet.Unknown04();
00367         m_socket->Packet(packet);
00368         expect = packet.Size();
00369 
00370         if (expect == 0)
00371                 return;
00372 
00373         // Read the data stream
00374         m_socket->Receive(response);
00375 
00376         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00377 
00378         // Check the size read into the previous packet
00379         if( expect != bytereceived ) {
00380                 ThrowJVMError("JVMDebug::Attach expect", expect);
00381         }
00382 }
00383 
00384 
00385 //
00386 // Unknown 05 ???
00387 //
00388 void JVMDebug::Unknown05()
00389 {
00390         uint16_t expect = 0;
00391 
00392         Data command(-1, 8), response;
00393         JVMPacket packet(command, response);
00394 
00395         // Send the command packet
00396         packet.Unknown05();
00397         m_socket->Packet(packet);
00398         expect = packet.Size();
00399 
00400         if (expect == 0)
00401                 return;
00402 
00403         // Read the data stream
00404         m_socket->Receive(response);
00405 
00406         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00407 
00408         // Check the size read into the previous packet
00409         if( expect != bytereceived ) {
00410                 ThrowJVMError("JVMDebug::Attach expect", expect);
00411         }
00412 }
00413 
00414 
00415 //
00416 // Unknown 06 ???
00417 //
00418 void JVMDebug::Unknown06()
00419 {
00420         uint16_t expect = 0;
00421 
00422         Data command(-1, 8), response;
00423         JVMPacket packet(command, response);
00424 
00425         // Send the command packet
00426         packet.Unknown06();
00427         m_socket->Packet(packet);
00428         expect = packet.Size();
00429 
00430         if (expect == 0)
00431                 return;
00432 
00433         // Read the data stream
00434         m_socket->Receive(response);
00435 
00436         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00437 
00438         // Check the size read into the previous packet
00439         if( expect != bytereceived ) {
00440                 ThrowJVMError("JVMDebug::Attach expect", expect);
00441         }
00442 }
00443 
00444 
00445 //
00446 // Unknown 07 ???
00447 //
00448 void JVMDebug::Unknown07()
00449 {
00450         uint16_t expect = 0;
00451 
00452         Data command(-1, 8), response;
00453         JVMPacket packet(command, response);
00454 
00455         // Send the command packet
00456         packet.Unknown07();
00457         m_socket->Packet(packet);
00458         expect = packet.Size();
00459 
00460         if (expect == 0)
00461                 return;
00462 
00463         // Read the data stream
00464         m_socket->Receive(response);
00465 
00466         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00467 
00468         // Check the size read into the previous packet
00469         if( expect != bytereceived ) {
00470                 ThrowJVMError("JVMDebug::Attach expect", expect);
00471         }
00472 }
00473 
00474 
00475 //
00476 // Unknown 08 ???
00477 //
00478 void JVMDebug::Unknown08()
00479 {
00480         uint16_t expect = 0;
00481 
00482         Data command(-1, 8), response;
00483         JVMPacket packet(command, response);
00484 
00485         // Send the command packet
00486         packet.Unknown08();
00487         m_socket->Packet(packet);
00488         expect = packet.Size();
00489 
00490         if (expect == 0)
00491                 return;
00492 
00493         // Read the data stream
00494         m_socket->Receive(response);
00495 
00496         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00497 
00498         // Check the size read into the previous packet
00499         if( expect != bytereceived ) {
00500                 ThrowJVMError("JVMDebug::Attach expect", expect);
00501         }
00502 }
00503 
00504 
00505 //
00506 // Unknown 09 ???
00507 //
00508 void JVMDebug::Unknown09()
00509 {
00510         uint16_t expect = 0;
00511 
00512         Data command(-1, 8), response;
00513         JVMPacket packet(command, response);
00514 
00515         // Send the command packet
00516         packet.Unknown09();
00517         m_socket->Packet(packet);
00518         expect = packet.Size();
00519 
00520         if (expect == 0)
00521                 return;
00522 
00523         // Read the data stream
00524         m_socket->Receive(response);
00525 
00526         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00527 
00528         // Check the size read into the previous packet
00529         if( expect != bytereceived ) {
00530                 ThrowJVMError("JVMDebug::Attach expect", expect);
00531         }
00532 }
00533 
00534 
00535 //
00536 // Unknown 10 ???
00537 //
00538 void JVMDebug::Unknown10()
00539 {
00540         uint16_t expect = 0;
00541 
00542         Data command(-1, 8), response;
00543         JVMPacket packet(command, response);
00544 
00545         // Send the command packet
00546         packet.Unknown10();
00547         m_socket->Packet(packet);
00548         expect = packet.Size();
00549 
00550         if (expect == 0)
00551                 return;
00552 
00553         // Read the data stream
00554         m_socket->Receive(response);
00555 
00556         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00557 
00558         // Check the size read into the previous packet
00559         if( expect != bytereceived ) {
00560                 ThrowJVMError("JVMDebug::Attach expect", expect);
00561         }
00562 }
00563 
00564 
00565 //
00566 // Get Status
00567 //
00568 bool JVMDebug::GetStatus(int &status)
00569 {
00570         uint16_t expect = 0;
00571 
00572         Data command(-1, 8), response;
00573         JVMPacket packet(command, response);
00574 
00575         // Send the command packet
00576         packet.GetStatus();
00577 
00578         m_socket->Packet(packet);
00579 
00580         expect = packet.Size();
00581 
00582         if (expect == 0)
00583                 return false;
00584 
00585         // Read the data stream
00586         m_socket->Receive(response);
00587 
00588         MAKE_JVMPACKET(dpack, response);
00589 
00590         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00591 
00592         // Check the size read into the previous packet
00593         if( expect != bytereceived ) {
00594                 ThrowJVMError("JVMDebug::GetModulesList expect", expect);
00595         }
00596 
00597         // Make sure we have a header to read
00598         CheckSize(response, SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.status));
00599 
00600         // Return status
00601         status = dpack->u.status;
00602 
00603         return true;
00604 }
00605 
00606 
00607 //
00608 // Wait Status
00609 //
00610 bool JVMDebug::WaitStatus(int &status)
00611 {
00612         uint16_t expect = 0;
00613 
00614         Data command(-1, 8), response;
00615         JVMPacket packet(command, response);
00616 
00617         // Prepare the command packet
00618         packet.GetStatus();
00619 
00620         try {
00621                 m_socket->Receive(packet.GetReceive(), 100);
00622         } catch (Usb::Timeout &to ) {
00623                 return false;
00624         }
00625 
00626         expect = packet.Size();
00627 
00628         if (expect == 0)
00629                 return false;
00630 
00631         // Read the data stream
00632         m_socket->Receive(response);
00633 
00634         MAKE_JVMPACKET(dpack, response);
00635 
00636         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00637 
00638         // Check the size read into the previous packet
00639         if( expect != bytereceived ) {
00640                 ThrowJVMError("JVMDebug::GetModulesList expect", expect);
00641         }
00642 
00643         // Make sure we have a header to read
00644         CheckSize(response, SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.status));
00645 
00646         // Return status
00647         status = dpack->u.status;
00648 
00649         return true;
00650 }
00651 
00652 
00653 //
00654 // Get Console Message
00655 // Sample, display the output of System.out.println(...) and all JVM messages output
00656 //
00657 // Return the length message or -1 if message doesn't exit or is empty
00658 //
00659 int JVMDebug::GetConsoleMessage(std::string &message)
00660 {
00661         uint16_t expect = 0;
00662 
00663         Data command(-1, 8), response;
00664         JVMPacket packet(command, response);
00665 
00666         // Send the command packet
00667         packet.GetConsoleMessage();
00668 
00669         m_socket->Packet(packet);
00670 
00671         expect = packet.Size();
00672 
00673         if (expect == 0)
00674                 return -1;
00675 
00676         // Read the data stream
00677         m_socket->Receive(response);
00678 
00679         MAKE_JVMPACKET(dpack, response);
00680 
00681         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00682 
00683         // Check the size read into the previous packet
00684         if( expect != bytereceived ) {
00685                 ThrowJVMError("JVMDebug::GetModulesList expect", expect);
00686         }
00687 
00688         // Make sure we have a header to read
00689         CheckSize(response, SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.msglength));
00690 
00691         // Length of message
00692         uint16_t length = be_btohs(dpack->u.msglength);
00693 
00694         if (length == 0)
00695                 return -1;
00696 
00697         CheckSize(response, SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.msglength) + length);
00698 
00699         // Parse the ID of nextmodules
00700         const unsigned char *ptr = (response.GetData() + SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.msglength));
00701 
00702         message.assign((char *) ptr, length);
00703 
00704         return length;
00705 }
00706 
00707 
00708 //
00709 // Get list of Java modules
00710 //
00711 void JVMDebug::GetModulesList(JVMModulesList &mylist)
00712 {
00713         uint32_t size = 0;
00714         uint32_t offset = 0;
00715         uint16_t expect = 0;
00716 
00717         Data command(-1, 8), response;
00718         JVMPacket packet(command, response);
00719 
00720         do {
00721                 // Send the command packet
00722                 packet.GetModulesList(offset);
00723 
00724                 m_socket->Packet(packet);
00725 
00726                 expect = packet.Size();
00727 
00728                 if (expect == 0)
00729                         break;
00730 
00731                 // Read the data stream
00732                 m_socket->Receive(response);
00733 
00734 //              MAKE_JVMPACKET(dpack, response);        // unused
00735 
00736                 size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00737 
00738                 // Check the size read into the previous packet
00739                 if( expect != bytereceived ) {
00740                         ThrowJVMError("JVMDebug::GetModulesList expect", expect);
00741                 }
00742 
00743                 // Make sure there's enough for packet header + module list
00744                 // header + 4 bytes of ID
00745                 CheckSize(response, SB_JVMPACKET_HEADER_SIZE + SB_JVMMODULES_LIST_HEADER_SIZE + 4);
00746 
00747                 // Number of modules entries in the list
00748                 // (Valid, but unused variable... disabled to stop compiler
00749                 // warnings)
00750 //              uint32_t count = be_btohl(dpack->u.moduleslist.nbr);
00751 
00752                 // Size of modules list
00753                 // I remove the header of packet (contains the field 'number of modules')
00754                 // and 4 bytes (contains the field 'ID of next modules')
00755                 size = bytereceived - SB_JVMMODULES_LIST_HEADER_SIZE - 4;
00756 
00757                 // Parse the modules list
00758                 mylist.Parse(Data(response.GetData() + SB_JVMPACKET_HEADER_SIZE + SB_JVMMODULES_LIST_HEADER_SIZE, size));
00759 
00760                 // Parse the ID of nextmodules
00761                 size_t id_offset = SB_JVMPACKET_HEADER_SIZE + SB_JVMMODULES_LIST_HEADER_SIZE + size;
00762                 const unsigned char *ptr = (response.GetData() + id_offset);
00763                 CheckSize(response, id_offset + sizeof(uint32_t));
00764                 uint32_t *poffset = (uint32_t *) ptr;
00765 
00766                 offset = be_btohl(*poffset);
00767         } while (offset != 0);  // When the offset != 0, there is some modules
00768 }
00769 
00770 
00771 //
00772 // Get list of Java threads
00773 //
00774 void JVMDebug::GetThreadsList(JVMThreadsList &mylist)
00775 {
00776         uint32_t size = 0;
00777         uint16_t expect = 0;
00778 
00779         Data command(-1, 8), response;
00780         JVMPacket packet(command, response);
00781 
00782         // Send the command packet
00783         packet.GetThreadsList();
00784 
00785         m_socket->Packet(packet);
00786 
00787         expect = packet.Size();
00788 
00789         if (expect == 0)
00790                 return;
00791 
00792         // Read the data stream
00793         m_socket->Receive(response);
00794 
00795 //      MAKE_JVMPACKET(dpack, response);        // unused
00796 
00797         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00798 
00799         // Check the size read into the previous packet
00800         if( expect != bytereceived ) {
00801                 ThrowJVMError("JVMDebug::GetThreadsList expect", expect);
00802         }
00803 
00804         CheckSize(response, SB_JVMPACKET_HEADER_SIZE + SB_JVMTHREADS_LIST_HEADER_SIZE);
00805 
00806         // Number of threads entries in the list
00807         // (Valid, but unused variable... disabled to stop compiler warnings)
00808 //      uint32_t count = be_btohl(dpack->u.threadslist.nbr);
00809 
00810         // Size of threads list
00811         // I remove the header of packet (contains the field 'number of threads')
00812         size = bytereceived - SB_JVMTHREADS_LIST_HEADER_SIZE;
00813 
00814         // Parse the threads list
00815         mylist.Parse(Data(response.GetData() + SB_JVMPACKET_HEADER_SIZE + SB_JVMTHREADS_LIST_HEADER_SIZE, size));
00816 
00817         // Complete threads list
00818         JVMThreadsList::iterator b = mylist.begin();
00819         for( ; b != mylist.end(); b++ ) {
00820                 JVMThreadsEntry entry = (*b);
00821 
00822                 // 1°/
00823                 // Send the command packet
00824                 packet.Unknown11(entry.Id);
00825 
00826                 m_socket->Packet(packet);
00827 
00828                 expect = packet.Size();
00829 
00830                 if (expect == 0)
00831                         return;
00832 
00833                 // Read the data stream
00834                 m_socket->Receive(response);
00835 
00836                 MAKE_JVMPACKET(dpack, response);
00837 
00838                 bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00839 
00840                 // Check the size read into the previous packet
00841                 if( expect != bytereceived ) {
00842                         ThrowJVMError("JVMDebug::GetThreadsList (1) expect", expect);
00843                 }
00844 
00845                 CheckSize(response, SB_JVMPACKET_HEADER_SIZE + SB_JVMUNKNOWN01_HEADER_SIZE);
00846 
00847                 // Save values
00848                 entry.Byte = dpack->u.unknown01.byte;
00849                 entry.Address = be_btohl(dpack->u.unknown01.address);
00850 
00851                 // 2°/
00852                 if (entry.Address != 0) {
00853                         // Send the command packet
00854                         packet.Unknown12(entry.Address);
00855 
00856                         m_socket->Packet(packet);
00857 
00858                         expect = packet.Size();
00859 
00860                         if (expect == 0)
00861                                 return;
00862 
00863                         // Read the data stream
00864                         m_socket->Receive(response);
00865 
00866                         MAKE_JVMPACKET(dpack, response);
00867 
00868                         bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00869 
00870                         // Check the size read into the previous packet
00871                         if( expect != bytereceived ) {
00872                                 ThrowJVMError("JVMDebug::GetThreadsList (2) expect", expect);
00873                         }
00874 
00875 
00876                         // Save values
00877                         CheckSize(response, SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.address));
00878                         entry.Unknown01 = be_btohl(dpack->u.address);
00879                 }
00880                 else
00881                         entry.Unknown01 = 0;
00882 
00883                 // 3°/
00884                 // Send the command packet
00885                 packet.Unknown13(entry.Id);
00886 
00887                 m_socket->Packet(packet);
00888 
00889                 expect = packet.Size();
00890 
00891                 if (expect == 0)
00892                         return;
00893 
00894                 // Read the data stream
00895                 m_socket->Receive(response);
00896 
00897                 dpack = (const Protocol::JVMPacket *) response.GetData();
00898 
00899                 bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00900 
00901                 // Check the size read into the previous packet
00902                 if( expect != bytereceived ) {
00903                         ThrowJVMError("JVMDebug::GetThreadsList (2) expect", expect);
00904                 }
00905 
00906                 // Save values
00907                 CheckSize(response, SB_JVMPACKET_HEADER_SIZE + sizeof(dpack->u.address));
00908                 entry.Unknown02 = be_btohl(dpack->u.address);
00909 
00910                 // 4°/
00911                 // Send the command packet
00912                 packet.Unknown14(entry.Id);
00913 
00914                 m_socket->Packet(packet);
00915 
00916                 expect = packet.Size();
00917 
00918                 if (expect == 0)
00919                         return;
00920 
00921                 // Read the data stream
00922                 m_socket->Receive(response);
00923 
00924                 dpack = (const Protocol::JVMPacket *) response.GetData();
00925 
00926                 bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00927 
00928                 // Check the size read into the previous packet
00929                 if( expect != bytereceived ) {
00930                         ThrowJVMError("JVMDebug::GetThreadsList (2) expect", expect);
00931                 }
00932 
00933                 // Save values
00934                 CheckSize(response, SB_JVMPACKET_HEADER_SIZE + SB_JVMUNKNOWN02_HEADER_SIZE);
00935                 entry.Unknown03 = be_btohl(dpack->u.unknown02.address1);
00936                 entry.Unknown04 = be_btohl(dpack->u.unknown02.address2);
00937 
00938                 // 5°/
00939                 // Send the command packet
00940                 packet.Unknown15(entry.Id);
00941 
00942                 m_socket->Packet(packet);
00943 
00944                 expect = packet.Size();
00945 
00946                 if (expect == 0)
00947                         return;
00948 
00949                 // Read the data stream
00950                 m_socket->Receive(response);
00951 
00952                 dpack = (const Protocol::JVMPacket *) response.GetData();
00953 
00954                 bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00955 
00956                 // Check the size read into the previous packet
00957                 if( expect != bytereceived ) {
00958                         ThrowJVMError("JVMDebug::GetThreadsList (2) expect", expect);
00959                 }
00960 
00961                 // Save values
00962                 CheckSize(response, SB_JVMPACKET_HEADER_SIZE + SB_JVMUNKNOWN02_HEADER_SIZE);
00963                 entry.Unknown05 = be_btohl(dpack->u.unknown02.address1);
00964                 entry.Unknown06 = be_btohl(dpack->u.unknown02.address2);
00965 
00966                 // Save...
00967                 (*b) = entry;
00968         }
00969 }
00970 
00971 
00972 //
00973 // Go
00974 //
00975 void JVMDebug::Go()
00976 {
00977         uint16_t expect = 0;
00978 
00979         Data command(-1, 8), response;
00980         JVMPacket packet(command, response);
00981 
00982         // Send the command packet
00983         packet.Go();
00984         m_socket->Packet(packet);
00985         expect = packet.Size();
00986 
00987         while (expect == 0) {
00988                 m_socket->Receive(packet.GetReceive());
00989 
00990                 expect = packet.Size();
00991         }
00992 
00993         // Read the data stream
00994         m_socket->Receive(response);
00995 
00996         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
00997 
00998         // Check the size read into the previous packet
00999         if( expect != bytereceived ) {
01000                 ThrowJVMError("JVMDebug::Attach expect", expect);
01001         }
01002 }
01003 
01004 
01005 //
01006 // Stop
01007 //
01008 void JVMDebug::Stop()
01009 {
01010         uint16_t expect = 0;
01011 
01012         Data command(-1, 8), response;
01013         JVMPacket packet(command, response);
01014 
01015         // Send the command packet
01016         packet.Stop();
01017         m_socket->Packet(packet);
01018         expect = packet.Size();
01019 
01020         while (expect == 0) {
01021                 m_socket->Receive(packet.GetReceive());
01022 
01023                 expect = packet.Size();
01024         }
01025 
01026         // Read the data stream
01027         m_socket->Receive(response);
01028 
01029         size_t bytereceived = response.GetSize() - SB_JVMPACKET_HEADER_SIZE;
01030 
01031         // Check the size read into the previous packet
01032         if( expect != bytereceived ) {
01033                 ThrowJVMError("JVMDebug::Attach expect", expect);
01034         }
01035 }
01036 
01037 
01038 }} // namespace Barry::Mode
01039