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