# 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