2 /// \file m_javadebug.cc
3 /// Mode class for the JavaDebug mode
7 Copyright (C) 2005-2009, Net Direct Inc. (http://www.netdirect.ca/)
8 Copyright (C) 2008-2009, Nicolas VIVIEN
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #include "m_javadebug.h"
26 #include "protostructs.h"
31 #include "controller.h"
47 ///////////////////////////////////////////////////////////////////////////////
48 // JDModulesList class
50 void JDModulesList::Parse(const Data
&entry_packet
)
54 size_t size
= entry_packet
.GetSize();
56 while (count
< size
) {
59 const unsigned char *ptr
= (entry_packet
.GetData() + count
);
60 Protocol::JDModulesEntry
*e
= (Protocol::JDModulesEntry
*) ptr
;
62 len
= SB_JDMODULES_ENTRY_HEADER_SIZE
+ be_btohs(e
->sizename
);
66 entry
.Id
= be_btohl(e
->id
);
67 entry
.Address
= be_btohl(e
->address
);
68 (entry
.Name
).assign((char *) (ptr
+ SB_JDMODULES_ENTRY_HEADER_SIZE
), be_btohs(e
->sizename
));
77 void JDModulesList::Dump(std::ostream
&os
) const
79 const_iterator i
= begin(), e
= end();
82 os
<< " Address " << "|";
83 os
<< " Module Name" << endl
;
85 os
<< "------------+";
86 os
<< "------------+";
87 os
<< "-------------";
90 for( ; i
!= e
; ++i
) {
96 ///////////////////////////////////////////////////////////////////////////////
97 // JDModulesEntry class
99 void JDModulesEntry::Dump(std::ostream
&os
) const
101 os
<< " 0x" << setfill('0') << setw(8) << hex
<< Id
<< " |";
102 os
<< " 0x" << setfill('0') << setw(8) << hex
<< Address
<< " |";
103 os
<< " " << Name
<< endl
;
107 ///////////////////////////////////////////////////////////////////////////////
108 // JDThreadsList class
110 void JDThreadsList::Parse(const Data
&entry_packet
)
114 size_t size
= entry_packet
.GetSize();
116 while (count
< size
) {
119 const unsigned char *ptr
= (entry_packet
.GetData() + count
);
120 uint32_t *e
= (uint32_t *) ptr
;
122 len
= sizeof(uint32_t);
124 JDThreadsEntry entry
;
126 entry
.Id
= be_btohl(*e
);
135 void JDThreadsList::Dump(std::ostream
&os
) const
137 const_iterator i
= begin(), e
= end();
139 os
<< " Thread " << "|";
140 os
<< " Byte " << "|";
141 os
<< " Address " << "|";
142 os
<< " Unknown01 " << "|";
143 os
<< " Unknown02 " << "|";
144 os
<< " Unknown03 " << "|";
145 os
<< " Unknown04 " << "|";
146 os
<< " Unknown05 " << "|";
147 os
<< " Unknown06 " << "|";
149 os
<< "------------+";
151 os
<< "------------+";
152 os
<< "------------+";
153 os
<< "------------+";
154 os
<< "------------+";
155 os
<< "------------+";
156 os
<< "------------+";
157 os
<< "-------------";
160 for(int k
=0 ; i
!= e
; ++i
, k
++ ) {
166 void JDThreadsEntry::Dump(std::ostream
&os
, int num
) const
168 os
<< " " << setfill(' ') << setw(8) << dec
<< num
<< " |";
169 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Id
) << " |";
170 os
<< " 0x" << setfill('0') << setw(2) << hex
<< (Byte
) << " |";
171 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Address
) << " |";
172 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Unknown01
) << " |";
173 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Unknown02
) << " |";
174 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Unknown03
) << " |";
175 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Unknown04
) << " |";
176 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Unknown05
) << " |";
177 os
<< " 0x" << setfill('0') << setw(8) << hex
<< (Unknown06
) << endl
;
183 ///////////////////////////////////////////////////////////////////////////////
184 // JavaDebug Mode class
186 JavaDebug::JavaDebug(Controller
&con
)
187 : Mode(con
, Controller::JavaDebug
)
192 JavaDebug::~JavaDebug()
198 ///////////////////////////////////////////////////////////////////////////////
202 ///////////////////////////////////////////////////////////////////////////////
205 void JavaDebug::OnOpen()
207 m_socket
->InitSequence();
213 /// These commands are sent to prepare the debug communication.
214 /// Must be called at the start of a JavaDebug session.
216 void JavaDebug::Attach()
223 /// Must be called at the end of a JavaDebug session. The JD_GOODBYE
224 /// command is sent to the device.
226 void JavaDebug::Detach()
231 void JavaDebug::ThrowJDError(const std::string
&msg
, uint8_t cmd
)
233 std::ostringstream oss
;
234 oss
<< msg
<< ": unexpected packet command code: 0x"
235 << std::hex
<< (unsigned int) cmd
;
236 throw Error(oss
.str());
243 void JavaDebug::Unknown01()
247 Data
command(-1, 8), response
;
248 JDPacket
packet(command
, response
);
250 // Send the command packet
252 m_socket
->Packet(packet
);
253 expect
= packet
.Size();
258 // Read the data stream
259 m_socket
->ReceiveData(response
);
261 size_t bytereceived
= response
.GetSize() - 4;
263 // Check the size read into the previous packet
264 if( expect
!= bytereceived
) {
265 ThrowJDError("JavaDebug::Attach expect", expect
);
273 void JavaDebug::Unknown02()
277 Data
command(-1, 8), response
;
278 JDPacket
packet(command
, response
);
280 // Send the command packet
282 m_socket
->Packet(packet
);
283 expect
= packet
.Size();
288 // Read the data stream
289 m_socket
->ReceiveData(response
);
291 size_t bytereceived
= response
.GetSize() - 4;
293 // Check the size read into the previous packet
294 if( expect
!= bytereceived
) {
295 ThrowJDError("JavaDebug::Attach expect", expect
);
303 void JavaDebug::Unknown03()
307 Data
command(-1, 8), response
;
308 JDPacket
packet(command
, response
);
310 // Send the command packet
312 m_socket
->Packet(packet
);
313 expect
= packet
.Size();
318 // Read the data stream
319 m_socket
->ReceiveData(response
);
321 size_t bytereceived
= response
.GetSize() - 4;
323 // Check the size read into the previous packet
324 if( expect
!= bytereceived
) {
325 ThrowJDError("JavaDebug::Attach expect", expect
);
333 void JavaDebug::Unknown04()
337 Data
command(-1, 8), response
;
338 JDPacket
packet(command
, response
);
340 // Send the command packet
342 m_socket
->Packet(packet
);
343 expect
= packet
.Size();
348 // Read the data stream
349 m_socket
->ReceiveData(response
);
351 size_t bytereceived
= response
.GetSize() - 4;
353 // Check the size read into the previous packet
354 if( expect
!= bytereceived
) {
355 ThrowJDError("JavaDebug::Attach expect", expect
);
363 void JavaDebug::Unknown05()
367 Data
command(-1, 8), response
;
368 JDPacket
packet(command
, response
);
370 // Send the command packet
372 m_socket
->Packet(packet
);
373 expect
= packet
.Size();
378 // Read the data stream
379 m_socket
->ReceiveData(response
);
381 size_t bytereceived
= response
.GetSize() - 4;
383 // Check the size read into the previous packet
384 if( expect
!= bytereceived
) {
385 ThrowJDError("JavaDebug::Attach expect", expect
);
393 void JavaDebug::Unknown06()
397 Data
command(-1, 8), response
;
398 JDPacket
packet(command
, response
);
400 // Send the command packet
402 m_socket
->Packet(packet
);
403 expect
= packet
.Size();
408 // Read the data stream
409 m_socket
->ReceiveData(response
);
411 size_t bytereceived
= response
.GetSize() - 4;
413 // Check the size read into the previous packet
414 if( expect
!= bytereceived
) {
415 ThrowJDError("JavaDebug::Attach expect", expect
);
423 void JavaDebug::Unknown07()
427 Data
command(-1, 8), response
;
428 JDPacket
packet(command
, response
);
430 // Send the command packet
432 m_socket
->Packet(packet
);
433 expect
= packet
.Size();
438 // Read the data stream
439 m_socket
->ReceiveData(response
);
441 size_t bytereceived
= response
.GetSize() - 4;
443 // Check the size read into the previous packet
444 if( expect
!= bytereceived
) {
445 ThrowJDError("JavaDebug::Attach expect", expect
);
453 void JavaDebug::Unknown08()
457 Data
command(-1, 8), response
;
458 JDPacket
packet(command
, response
);
460 // Send the command packet
462 m_socket
->Packet(packet
);
463 expect
= packet
.Size();
468 // Read the data stream
469 m_socket
->ReceiveData(response
);
471 size_t bytereceived
= response
.GetSize() - 4;
473 // Check the size read into the previous packet
474 if( expect
!= bytereceived
) {
475 ThrowJDError("JavaDebug::Attach expect", expect
);
483 void JavaDebug::Unknown09()
487 Data
command(-1, 8), response
;
488 JDPacket
packet(command
, response
);
490 // Send the command packet
492 m_socket
->Packet(packet
);
493 expect
= packet
.Size();
498 // Read the data stream
499 m_socket
->ReceiveData(response
);
501 size_t bytereceived
= response
.GetSize() - 4;
503 // Check the size read into the previous packet
504 if( expect
!= bytereceived
) {
505 ThrowJDError("JavaDebug::Attach expect", expect
);
513 void JavaDebug::Unknown10()
517 Data
command(-1, 8), response
;
518 JDPacket
packet(command
, response
);
520 // Send the command packet
522 m_socket
->Packet(packet
);
523 expect
= packet
.Size();
528 // Read the data stream
529 m_socket
->ReceiveData(response
);
531 size_t bytereceived
= response
.GetSize() - 4;
533 // Check the size read into the previous packet
534 if( expect
!= bytereceived
) {
535 ThrowJDError("JavaDebug::Attach expect", expect
);
543 bool JavaDebug::GetStatus(int &status
)
547 Data
command(-1, 8), response
;
548 JDPacket
packet(command
, response
);
550 // Send the command packet
553 m_socket
->Packet(packet
);
555 expect
= packet
.Size();
560 // Read the data stream
561 m_socket
->ReceiveData(response
);
563 MAKE_JDPACKET(dpack
, response
);
565 size_t bytereceived
= response
.GetSize() - 4;
567 // Check the size read into the previous packet
568 if( expect
!= bytereceived
) {
569 ThrowJDError("JavaDebug::GetModulesList expect", expect
);
573 status
= dpack
->u
.status
;
582 bool JavaDebug::WaitStatus(int &status
)
586 Data
command(-1, 8), response
;
587 JDPacket
packet(command
, response
);
589 // Prepare the command packet
593 m_socket
->Receive(packet
.GetReceive(), 100);
594 } catch (Usb::Timeout
&to
) {
598 expect
= packet
.Size();
603 // Read the data stream
604 m_socket
->ReceiveData(response
);
606 MAKE_JDPACKET(dpack
, response
);
608 size_t bytereceived
= response
.GetSize() - 4;
610 // Check the size read into the previous packet
611 if( expect
!= bytereceived
) {
612 ThrowJDError("JavaDebug::GetModulesList expect", expect
);
616 status
= dpack
->u
.status
;
623 // Get Console Message
624 // Sample, display the output of System.out.println(...) and all JVM messages output
626 // Return the length message or -1 if message doesn't exit or is empty
628 int JavaDebug::GetConsoleMessage(std::string
&message
)
632 Data
command(-1, 8), response
;
633 JDPacket
packet(command
, response
);
635 // Send the command packet
636 packet
.GetConsoleMessage();
638 m_socket
->Packet(packet
);
640 expect
= packet
.Size();
645 // Read the data stream
646 m_socket
->ReceiveData(response
);
648 MAKE_JDPACKET(dpack
, response
);
650 size_t bytereceived
= response
.GetSize() - 4;
652 // Check the size read into the previous packet
653 if( expect
!= bytereceived
) {
654 ThrowJDError("JavaDebug::GetModulesList expect", expect
);
658 uint16_t length
= be_btohs(dpack
->u
.msglength
);
663 // Parse the ID of nextmodules
664 const unsigned char *ptr
= (response
.GetData() + SB_JDPACKET_HEADER_SIZE
+ sizeof(uint16_t));
666 message
.assign((char *) ptr
, length
);
673 // Get list of Java modules
675 void JavaDebug::GetModulesList(JDModulesList
&mylist
)
682 Data
command(-1, 8), response
;
683 JDPacket
packet(command
, response
);
686 // Send the command packet
687 packet
.GetModulesList(offset
);
689 m_socket
->Packet(packet
);
691 expect
= packet
.Size();
696 // Read the data stream
697 m_socket
->ReceiveData(response
);
699 MAKE_JDPACKET(dpack
, response
);
701 size_t bytereceived
= response
.GetSize() - 4;
703 // Check the size read into the previous packet
704 if( expect
!= bytereceived
) {
705 ThrowJDError("JavaDebug::GetModulesList expect", expect
);
708 // Number of modules entries in the list
709 count
= be_btohl(dpack
->u
.moduleslist
.nbr
);
711 // Size of modules list
712 // I remove the header of packet (contains the field 'number of modules')
713 // and 4 bytes (contains the field 'ID of next modules')
714 size
= bytereceived
- SB_JDMODULES_LIST_HEADER_SIZE
- 4;
716 // Parse the modules list
717 mylist
.Parse(Data(response
.GetData() + SB_JDPACKET_HEADER_SIZE
+ SB_JDMODULES_LIST_HEADER_SIZE
, size
));
719 // Parse the ID of nextmodules
720 const unsigned char *ptr
= (response
.GetData() + SB_JDPACKET_HEADER_SIZE
+ SB_JDMODULES_LIST_HEADER_SIZE
+ size
);
721 uint32_t *poffset
= (uint32_t *) ptr
;
723 offset
= be_btohl(*poffset
);
724 } while (offset
!= 0); // When the offset != 0, there is some modules
729 // Get list of Java threads
731 void JavaDebug::GetThreadsList(JDThreadsList
&mylist
)
737 Data
command(-1, 8), response
;
738 JDPacket
packet(command
, response
);
740 // Send the command packet
741 packet
.GetThreadsList();
743 m_socket
->Packet(packet
);
745 expect
= packet
.Size();
750 // Read the data stream
751 m_socket
->ReceiveData(response
);
753 MAKE_JDPACKET(dpack
, response
);
755 size_t bytereceived
= response
.GetSize() - 4;
757 // Check the size read into the previous packet
758 if( expect
!= bytereceived
) {
759 ThrowJDError("JavaDebug::GetThreadsList expect", expect
);
762 // Number of threads entries in the list
763 count
= be_btohl(dpack
->u
.threadslist
.nbr
);
765 // Size of threads list
766 // I remove the header of packet (contains the field 'number of threads')
767 size
= bytereceived
- SB_JDTHREADS_LIST_HEADER_SIZE
;
769 // Parse the threads list
770 mylist
.Parse(Data(response
.GetData() + SB_JDPACKET_HEADER_SIZE
+ SB_JDTHREADS_LIST_HEADER_SIZE
, size
));
772 // Complete threads list
773 vector
<JDThreadsEntry
>::iterator b
= mylist
.begin();
774 for( ; b
!= mylist
.end(); b
++ ) {
775 JDThreadsEntry entry
= (*b
);
778 // Send the command packet
779 packet
.Unknown11(entry
.Id
);
781 m_socket
->Packet(packet
);
783 expect
= packet
.Size();
788 // Read the data stream
789 m_socket
->ReceiveData(response
);
791 dpack
= (const Protocol::JDPacket
*) response
.GetData();
793 bytereceived
= response
.GetSize() - 4;
795 // Check the size read into the previous packet
796 if( expect
!= bytereceived
) {
797 ThrowJDError("JavaDebug::GetThreadsList (1) expect", expect
);
801 entry
.Byte
= dpack
->u
.unknown01
.byte
;
802 entry
.Address
= be_btohl(dpack
->u
.unknown01
.address
);
805 if (entry
.Address
!= 0) {
806 // Send the command packet
807 packet
.Unknown12(entry
.Address
);
809 m_socket
->Packet(packet
);
811 expect
= packet
.Size();
816 // Read the data stream
817 m_socket
->ReceiveData(response
);
819 dpack
= (const Protocol::JDPacket
*) response
.GetData();
821 bytereceived
= response
.GetSize() - 4;
823 // Check the size read into the previous packet
824 if( expect
!= bytereceived
) {
825 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect
);
829 entry
.Unknown01
= be_btohl(dpack
->u
.address
);
835 // Send the command packet
836 packet
.Unknown13(entry
.Id
);
838 m_socket
->Packet(packet
);
840 expect
= packet
.Size();
845 // Read the data stream
846 m_socket
->ReceiveData(response
);
848 dpack
= (const Protocol::JDPacket
*) response
.GetData();
850 bytereceived
= response
.GetSize() - 4;
852 // Check the size read into the previous packet
853 if( expect
!= bytereceived
) {
854 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect
);
858 entry
.Unknown02
= be_btohl(dpack
->u
.address
);
861 // Send the command packet
862 packet
.Unknown14(entry
.Id
);
864 m_socket
->Packet(packet
);
866 expect
= packet
.Size();
871 // Read the data stream
872 m_socket
->ReceiveData(response
);
874 dpack
= (const Protocol::JDPacket
*) response
.GetData();
876 bytereceived
= response
.GetSize() - 4;
878 // Check the size read into the previous packet
879 if( expect
!= bytereceived
) {
880 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect
);
884 entry
.Unknown03
= be_btohl(dpack
->u
.unknown02
.address1
);
885 entry
.Unknown04
= be_btohl(dpack
->u
.unknown02
.address2
);
888 // Send the command packet
889 packet
.Unknown15(entry
.Id
);
891 m_socket
->Packet(packet
);
893 expect
= packet
.Size();
898 // Read the data stream
899 m_socket
->ReceiveData(response
);
901 dpack
= (const Protocol::JDPacket
*) response
.GetData();
903 bytereceived
= response
.GetSize() - 4;
905 // Check the size read into the previous packet
906 if( expect
!= bytereceived
) {
907 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect
);
911 entry
.Unknown05
= be_btohl(dpack
->u
.unknown02
.address1
);
912 entry
.Unknown06
= be_btohl(dpack
->u
.unknown02
.address2
);
924 Data
command(-1, 8), response
;
925 JDPacket
packet(command
, response
);
927 // Send the command packet
929 m_socket
->Packet(packet
);
930 expect
= packet
.Size();
932 while (expect
== 0) {
933 m_socket
->Receive(packet
.GetReceive());
935 expect
= packet
.Size();
938 // Read the data stream
939 m_socket
->ReceiveData(response
);
941 size_t bytereceived
= response
.GetSize() - 4;
943 // Check the size read into the previous packet
944 if( expect
!= bytereceived
) {
945 ThrowJDError("JavaDebug::Attach expect", expect
);
953 void JavaDebug::Stop()
957 Data
command(-1, 8), response
;
958 JDPacket
packet(command
, response
);
960 // Send the command packet
962 m_socket
->Packet(packet
);
963 expect
= packet
.Size();
965 while (expect
== 0) {
966 m_socket
->Receive(packet
.GetReceive());
968 expect
= packet
.Size();
971 // Read the data stream
972 m_socket
->ReceiveData(response
);
974 size_t bytereceived
= response
.GetSize() - 4;
976 // Check the size read into the previous packet
977 if( expect
!= bytereceived
) {
978 ThrowJDError("JavaDebug::Attach expect", expect
);
983 }} // namespace Barry::Mode