Giao diện với trình gỡ rối CDT, Phần 2: Truy cập gdb bằng CDT Eclipse và MI (Machine Interface)

Cách C/C++ Development Tooling (Công cụ phát triển C/C++) sử dụng C/C++ Debugger Interface (Giao diện trình gỡ rối C/C++) để làm việc với GNU Debugger's Machine Interface (Giao diện máy của trình gỡ rối GNU)

Môi trường gỡ rối đồ họa được cung cấp bởi C/C++ Development Tooling (CDT- Công cụ phát triển C/C++) Eclipse tốt như nó nhận được, hiển thị các điểm ngắt (breakpoints), các điểm giám sát (watchpoints), các biến, các danh sách đăng ký, tháo gỡ, các tín hiệu và các nội dung bộ nhớ. Bạn có thể thêm các khả năng mới cho môi trường này hoặc truy cập các khung nhìn này để hiển thị kết xuất từ một trình gỡ rối tùy chỉnh. Nhưng trước tiên, bạn cần phải hiểu C/C++ Debugger Interface (CDI - Giao diện trình gỡ rối C/C++) và cách nó giao tiếp với Eclipse. Phần 1 của loạt bài "Giao diện với trình gỡ CDT" (Interfacing with the CDT debugger) mô tả CDI ở mức cao. Tại đây trong Phần 2, hãy tìm hiểu cách CDT nói với GNU Debugger (gdb –trình gỡ rối GNU). Đặc biệt là tìm hiểu cách CDT sử dụng CDI và Machine Interface (MI – Giao diện máy) để giao diện với gdb.

Matthew Scarpino, Phát triển Java, Eclipse Engineering, LLC

Matthew Scarpino là nhà quản lý dự án và nhà phát triển Java tại Eclipse Engineering LLC. Ông là tác giả hàng đầu của SWT/JFace in Action và có đóng góp nhỏ nhưng quan trọng vào Standard Widget Toolkit (SWT). Ông thích nhạc dân gian Ailen, chạy maratông, thơ của William Blake, và Graphical Editing Framework (GEF).


Cấp độ đóng góp cho developerWorks của
        tác giả

23 10 2009

GNU Debugger (gdb) là trình gỡ rối mã nguồn mở phổ biến nhất đang sử dụng. Ban đầu được thiết kế dành cho C, nó được chuyển sang để gỡ rối mã trong nhiều ngôn ngữ trên nhiều hệ thống tính toán, từ các thiết bị nhúng nhỏ đến các siêu máy tính quy mô lớn. Nó thường được dùng như một dòng lệnh trực khai, nhưng nó có thể được truy cập thông qua phần mềm bằng cách sử dụng giao thức MI ít được biết đến. Bài viết này giải thích cách MI làm việc và cách CDT sử dụng MI để giao tiếp với gdb. Ví dụ cụ thể này về tương tác trình gỡ rối-CDT sẽ có ích cho bất cứ ai muốn vào giao diện với trình gỡ rối C/C++ tuỳ chỉnh từ CDT.

Các lớp Java™ đã thảo luận ở đây xây dựng trên các lớp và các giao diện do CDI cung cấp, được giới thiệu trong Phần 1 của loạt bài "Giao diện với trình gỡ CDT" này. Để loại bỏ bất kỳ sự nhầm lẫn nào, hãy làm rõ về sự khác biệt giữa CDI và MI:

  • CDI đã được các nhà phát triển Eclipse/CDT tạo ra để CDT có thể truy cập các trình gỡ rối bên ngoài.
  • MI đã được các nhà phát triển gdb tạo ra để các ứng dụng bên ngoài có thể truy cập gdb.

Điều này có thể trông như có một sự khác biệt đơn giản, nhưng nhiều trong số các lớp mà hiện tôi không dùng CDI lẫn MI, đôi khi khó có thể nhìn thấy một giao diện kết thúc và giao diện kế tiếp bắt đầu ở đâu. Một khi bạn hiểu cách CDI và MI hoạt động cùng nhau, bạn sẽ có khả năng tốt hơn để liên kết các công cụ gỡ rối tuỳ chỉnh với CDT, cho dù chúng có dựa trên gdb hay không.

Hiểu GNU Debugger Machine Interface (gdb/MI – Giao diện máy của trình gỡ rối GNU)

Hầu hết mọi người truy cập gdb từ một dòng lệnh, khi sử dụng hướng dẫn đơn giản như lúc đang chạy (run), in ấn (print) và thông tin (info). Đây là giao diện của con người (human) với gdb. Một phương pháp thứ hai về truy cập gdb đã được phát triển để giao diện với các trình gỡ rối bằng phần mềm: Giao diện máy (MI). Trình gỡ rối thực hiện cùng nhiệm vụ như trước, nhưng các lệnh và kết quả xuất ra khác nhau rất nhiều.

Một ví dụ sẽ làm cho điều này rõ ràng. Hãy nói rằng bạn muốn gỡ rối một ứng dụng dựa trên đoạn mã dưới đây.

Liệt kê 1. Một ứng dụng C đơn giản: simple.c
int main() {
    int x = 4;
	x += 6;		// x = 10
	x *= 5;		// x = 50
    return (0);
}

Sau khi bạn biên dịch mã bằng gcc -g -O0 simple.c -o simple, một phiên làm việc gỡ rối thông thường có thể trông giống như Liệt kê 2.

Liệt kê 2. Một phiên làm việc gỡ rối
 $ gdb -q simple (gdb) break main (gdb) run
1	int main() {
(gdb) step
2	int x = 4;
(gdb) step
3	x += 6;     // x = 10
(gdb) print x
$1 = 4
(gdb) step
4	x *= 5;     // x = 50
(gdb) print x
$2 = 10
(gdb) quit

Liệt kê 3 cho thấy phiên làm việc gdb khi sử dụng các lệnh MI (được in đậm).

Liệt kê 3. Một phiên làm việc gỡ rối có dùng MI
$ gdb -q -i mi simple
(gdb)
-break-insert-main
^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00401075",
func="main",file="simple.c",fullname="/home/mscarpino/simple.c",line="1",times="0"}
(gdb)
-exec-run
^running
(gdb)
*stopped,reason="breakpoint-hit",bkptno="1",thread-id="1",frame={addr="0x00401075",
func="main",args=[],file="simple.c",fullname="/home/mscarpino/simple.c",line="1"}
(gdb)
-exec-step
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x0040107a",
func="main",args=[],file="simple.c",fullname="/home/mscarpino/simple.c",line="2"}
(gdb)
-exec-step
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x00401081",
func="main",args=[],file="simple.c",fullname="/home/mscarpino/simple.c",line="3"}
(gdb)
-var-create x_name * x
^done,name="x_name",numchild="0",type="int"
(gdb)
-var-evaluate-expression x_name
^done,value="4"
(gdb)
-exec-step
^running
(gdb)
*stopped,reason="end-stepping-range",thread-id="1",frame={addr="0x00401081",
func="main",args=[],file="simple.c",fullname="/home/mscarpino/simple.c",line="4"}
(gdb)
-var-update x_name
^done,changelist=[{name="x_name",in_scope="true",type_changed="false"}]
(gdb)
-var-evaluate-expression x_name
^done,value="10"
(gdb)
-var-delete x_name
^done,ndeleted="1"
(gdb)
-gdb-exit

Cờ -i mi nói cho gdb biết để giao tiếp sử dụng giao thức MI và bạn có thể thấy sự khác biệt đáng kể. Các tên lệnh đã thay đổi nhiều và do đó có bản chất của kết xuất. Dòng đầu tiên của bản ghi đầu ra hoặc là ^running hoặc ^done, đã thực hiện, tiếp theo là thông tin kết quả. Kết xuất này được gọi là bản ghi kết quả (result record) và nó có thể gồm ^error lỗi và một thông báo lỗi.

Trong nhiều trường hợp, bản ghi kết quả MI có theo sau (gdb) và một bản ghi ngoài dải (OOB). Các bản ghi này cung cấp thông tin bổ sung về trạng thái của môi trường đích hay môi trường gỡ rối. Thông báo *stopped sau bước -exec-step là một bản ghi OOB, cung cấp thông tin về các điểm ngắt, các điểm giám sát và lí do đích đó đã tạm dừng hoặc kết thúc. Trong phiên làm việc trước đó *stopped,reason="end-stepping-range" trả về -exec-step, cùng với trạng thái đích.

gdb/MI MI khó hiểu cho mọi người, nhưng nó lý tưởng cho truyền thông giữa các quá trình phần mềm. CDT kích hoạt truyền thông này bằng cách tạo ra một thiết bị đầu cuối giả (Pty) để gửi và nhận dữ liệu. Sau đó, nó khởi động gdb và tạo ra hai đối tượng phiên làm việc để quản lý dữ liệu gỡ rối.


Bắt đầu việc gỡ rối

Như mô tả ở Phần 1, khi người dùng nhấn Debug, CDT sẽ truy cập một cá thể ICDebugger2 và gọi tới nó để tạo ra một ICDISession. Lớp trình gỡ rối này phải được xác định trong một trình cắm thêm để sang điểm mở rộng org.eclipse.cdt.debug.core.CDebugger. Liệt kê 4 cho thấy phần mở rộng này trong CDT.

Liệt kê 4. Phần mở rộng trình gỡ rối mặc định CDT
   <extension point="org.eclipse.cdt.debug.core.CDebugger">
      <debugger
            class="org.eclipse.cdt.debug.mi.core.GDBCDIDebugger2"
            cpu="native"
            id="org.eclipse.cdt.debug.mi.core.CDebuggerNew"
            modes="run,core,attach"
            name="gdb Debugger"
            platform="*">
         <buildIdPattern
               pattern="cdt\.managedbuild\.config\.gnu\..*">
         </buildIdPattern>
      </debugger>
   </extension>

Điều này khẳng định GDBCDIDebugger2 triển khai thực hiện phương thức createSession() để bắt đầu quá trình gỡ rối. Khi CDT gọi phương thức này, nó cung cấp trình gỡ rối với đối tượng khởi chạy có chứa các tham số cấu hình, tên của tệp trực khaiđã được gỡ rối và bộ giám sát một tiến trình. GDBCDIDebugger2 sử dụng thông tin này để tạo thành một chuỗi mà chuỗi đó bắt đầu các gdb trực khai:

gdb -q -nw -i mi-version -tty pty-slaveexecutable-name.

GDBCDIDebugger2 tạo ra một MIProcess đang chạy là trực khai, sau đó tạo ra hai đối tượng phiên làm việc để quản lý phần còn lại của quá trình gỡ rối: MISessionSession. Đối tượng MISession quản lý truyền thông với gdb và đối tượng Session kết nối phiên làm việc gdb với CDI được mô tả trong Phần 1. Phần còn lại của bài viết này thảo luận về các đối tượng phiên làm việc một cách chi tiết.

MISession

Sau khi bắt đầu gdb, điều đầu tiên mà GDBCDIDebugger2 làm là tạo ra một đối tượng MISession. Đối tượng này xử lý tất cả các truy cập tới trình gỡ rối gdb bằng cách sử dụng ba cặp đối tượng:

  • Một đối tượng OutputStream để gửi dữ liệu đến quá trình gdb và một đối tượng InputStream để thu nhận kết quả của nó.
  • Một đối tượng CommandQueue vào và ra để tiến hành các lệnh MI.
  • Một đối tượng TxThread tgửi các lệnh từ đối tượng CommandQueue ra tới đối tượng OutputStream và một đối tượng RxThread nhận các lệnh từ đối tượng InputStream và đặt chúng tới đối tượng CommandQueue vào.

Một ví dụ sẽ thể hiện cách các đối tượng này làm việc cùng nhau. Nếu phiên làm việc gỡ rối được tiến hành từ xa, CDT khởi tạo truyền thông bằng cách gửi một lệnh remotebaud đến gdb, tiếp theo là tốc độ truyền (baud rate). Để hoàn thành việc này, nó gọi phương thức postCommand của đối tượng MISession, thêm lệnh remotebaud vào đối tượng ra CommandQueue. Điều này đánh thức đối tượng TxThread, nó viết lệnh tới đối tượng OutputStream đã kết nối với quá trình gdb. Nó cũng thêm lệnh tới CommandQueue vào phiên làm việc.

Trong khi đó RxThread liên tục đọc InputStream từ quá trình gdb. Khi một kết quả đầu ra mới đã sẵn sàng, RxThread gửi nó qua MIParser để thu nhận các bản ghi kết quả và bản ghi OOB. Sau đó nó tìm kiếm thông qua đối tượng vào CommandQueue để tìm lệnh gdb nhắc kết quả đầu ra. Khi RxThread hiểu kết quả đầu ra và lệnh tương ứng của gdb, nó tạo ra một MIEvent dùng để quảng bá sự thay đổi về trạng thái của trình gỡ rối.

Theo dữ liệu được chuyển đi và đến từ gdb, đối tượng TxThreadRxThread tạo và thực hiện các MIEvent.Ví dụ, nếu TxThread gửi một lệnh thay đổi một điểm ngắt đến gdb, nó tạo ra một MIBreakpointChangedEvent. Nếu RxThread nhận được một đáp ứng từ gdb mà bản ghi kết quả là ^running, nó tạo ra một MIRunningEvent. Các sự kiện này không phải là các sự thực hiện của giao diện ICDIEvent đã mô tả trong Phần 1. Để xem cách các MIEvent và các ICDIEvent quan hệ, bạn cần phải hiểu đối tượng Session.

Session, TargetEventManager

Sau khi tạo MISession, GDBCDIDebugger2 tạo một đối tượng Phiên làm việc (Session) để quản lý thao tác của CDI. Khi bộ tạo của nó được gọi, Session tạo nhiều đối tượng để trợ giúp các chức năng quản lý của nó. Hai đối tượng đặc biệt quan trọng Đích (Target), quản lý mô hình CDI và gửi các lệnh tới trình gỡ rối và Trình quản lý sự kiện (EventManager), nghe các MIEvent do trình gỡ rối tạo ra.

Như Phần 1 giải thích, Target nhận các lệnh gỡ rối từ CDT và đóng gói chúng cho trình gỡ rối. Ví dụ, khi bạn nhấn chuột vào nút Step Over, CDT tìm thấy Target hiện tại và gọi phương thức Target và gọi phương thức stepOver của nó. Target đáp ứng bằng cách tạo ra một lệnh MIExecNext và gọi phương thức MISession.postCommand() để thực hiện bước đó. MISession bổ sung lệnh vào CommandQueue ra của nó, ở đó nó được chuyển tới trình gỡ rối theo cách đã mô tả trước đó.

Kết quả đầu ra gdb, được đóng gói thành một MIEvent, được EventManager của phiên làm việc thu nhận. Khi đối tượng này được tạo, nó được thêm vào như là một trình theo dõi (Observer) cho MISession đang chạy. Khi MISession thực hiện các MIEvent, EventManager diễn giải chúng và tạo ra ICDIEvents tương ứng. Ví dụ, khi MISession thực hiện một MIRegisterChangedEvent, EventManager tạo ra một sự kiện CDI được gọi là ChangedEvent. Sau khi tạo sự kiện CDI này, EventManager thông báo cho tất cả những bộ nghe quan tâm rằng có sự thay đổi trạng thái đã xảy ra. Nhiều trong số những bộ nghe là các phần tử trong mô hình CDI, trừ ngoại lệ quan trọng đối với đối tượng tên là CDebugTarget. Đây là một phần của phân cấp mô hình khác, được giải thích sau.


Mô hình gỡ rối CDI và Eclipse

Với trình gỡ rối cắm thêm của bạn để giao tiếp với các khung nhìn debug Eclipse, chẳng hạn như Khung nhìn đăng ký (Register View) và Khung nhìn biến (Variable View), bạn phải theo các quy tắc của Eclipse: phải sử dụng các sự kiện và các phần tử mô hình nhận được từ nền tảng gỡ rối Eclipse. Phần tử gốc trong mô hình gỡ rối Eclipse là IDebugTarget và các phần tử khác gồm các IVariable, các IExpression và các IThread. Nếu các tên này trông quen thuộc, đó là vì hệ thống phân cấp của mô hình CDI được cấu trúc sau phân cấp mô hình gỡ rối Eclipse. Tuy nhiên, mô hình CDI và mô hình gỡ rối Eclipse không thể trao đổi trực tiếp với nhau.

Vì lý do này, CDT có tập các lớp bọc xung quanh các lớp CDI để đảm bảo cầu nối giữa mô hình CDI và mô hình gỡ rối Eclipse. CDebugTarget là gốc của phân cấp mô hình trình bao và nó theo dõi các sự kiện được CDI EventManager thực hiện. Khi nó thu nhận một sự kiện mới, CDebugTarget xử lý một tập lớn các câu lệnh ifswitch để xác định cách trả lời. Ví dụ, nếu sự kiện CDI là một ICDIResumedEvent, CDebugTarget thực thi mã trong Liệt kê 5.

Liệt kê 5. Biến đổi các sự kiện CDI thành DebugEvents
switch( event.getType() ) {
	case ICDIResumedEvent.CONTINUE:
		detail = DebugEvent.CLIENT_REQUEST;
		break;
	case ICDIResumedEvent.STEP_INTO:
	case ICDIResumedEvent.STEP_INTO_INSTRUCTION:
		detail = DebugEvent.STEP_INTO;
		break;
	case ICDIResumedEvent.STEP_OVER:
	case ICDIResumedEvent.STEP_OVER_INSTRUCTION:
	 detail = DebugEvent.STEP_OVER;
		break;
	case ICDIResumedEvent.STEP_RETURN:
		detail = DebugEvent.STEP_RETURN;
		break;
}

CDebugTarget đáp ứng các sự kiện CDI bằng cách tạo ra DebugEvents, thường liên quan đến bước nhảy, ngắt và bắt đầu lại một khai thác. Sau khi tạo ra những sự kiện này, nó truy cập vào DebugPlugin của Eclipse và gọi phương thức fireDebugEventSet của nó. Điều này thông báo cho tất cả những bộ nghe gỡ rối Eclipse rằng một sự thay đổi trạng thái đã xảy ra. Đó là, đối tượng bất kỳ mà thêm vào chính nó một DebugEventListener sẽ nhận DebugEvent. Điều này bao gồm các khung nhìn gỡ rối Eclipse, chẳng hạn như Khung nhìn bộ nhớ (Memory View) và Khung nhìn biến (Variables View).


Các khung nhìn gỡ rối CDT

Eclipse Trình bao CDI-MI là có ích chỉ khi nó cập nhật hiển thị đồ họa của Eclipse với dữ liệu gỡ rối phù hợp. Hình 1 chỉ ra phối cảnh gỡ rối CDT và bạn có thể thấy nhiều khung nhìn thể hiện trạng thái thực hiện đích. Nhiều trong số các khung nhìn — Các điểm ngắt (Breakpoints), Các mô đun (Modules) và Các biểu thức (Expressions) — do Eclipse cung cấp, nhưng CDT thêm ba khung nhìn vào viễn cảnh đó: Khung nhìn thực thi (Executables View), Khung nhìn gỡ bỏ (Disassembly View) và Các tín hiệu (Signals).

Hình 1. Phối cảnh gỡ rối CDT
Phối cảnh gỡ rối CDT

Các khung nhìn này tạo và nhận các sự kiện gỡ rối theo cách như nhau. Phần này giải thích khung nhìn Signals. Khung nhìn này, được hiển thị rõ ràng ở trên, liệt kê tất cả các tín hiệu mà đích có thể nhận và chỉ ra các tín hiệu có thể được chuyển tới tiến trình. Khi khung nhìn đầu tiên xuất hiện, SignalsViewContentProvider gọi CDebugTarget để cung cấp một danh sách các tín hiệu. Đích này truy cập đích CDI và yêu cầu nó cho các tín hiệu trong phân cấp mô hình-CDI. Khi mảng ICDISignals được trả về CDebugTarget cập nhật các phần tử mô hình của riêng nó và gửi chúng đến SignalsViewContentProvider, sử dụng chúng để đặt vào khung nhìn Signals.

Khi bạn phải nhấn chuột phải vào một mục nhập vào trong khung nhìn Signals, các tùy chọn trình đơn ngữ cảnh Resume with Signal (Tiếp tục với Tín hiệu) cho phép bạn tiếp tục việc thực thi của đích đó và gửi tín hiệu được chọn cho tiến trình. Tùy chọn này gọi SignalsActionDelegate. Khi tùy chọn này được chọn, trường đại diện (delegate) gọi đích CDI để tiếp tục việc thực thi của nó với ICDISignal tương ứng với tín hiệu được chọn. Đích này tạo một lệnh MI cho tín hiệu và gọi phương thức MISession.postCommand(), gửi lệnh tới gdb.

Khi gdb đáp ứng, quá trình cập nhật Khung nhìn Signals thực hiện năm bước sau:

  1. MISession phân tích đầu ra MI từ gdb và xác định xem một giá trị cài đặt tín hiệu có đang được thay đổi không. Nếu có, thì nó thực hiện MISignalChangedEvent.
  2. CDI EventManager nghe MISignalChangedEvent và đáp ứng bằng cách tạo ra một sự kiện CDI: ChangedEvent. Rồi nó thực hiện sự kiện và báo cho tất cả ICDIEventListeners.
  3. CDebugTarget nhận sự kiện từ EventManager và xác định xem ChangedEvent có liên quan đến một sự thay đổi tín hiệu không. Nếu đúng như vậy, nó gọi CSignalManager của nó để xử lý sự kiện CDI.
  4. CSignalManager cập nhật các phần tử mô hình của nó và thực hiện một DebugEvent mà kiểu của nó do DebugEvent.CHANGE đưa ra.
  5. SignalViewEventHandler thu nhận DebugEvent, kiểm tra để chắc chắn rằng nó xử lý các tín hiệu và làm mới Khung nhìn Signals.

Hiểu biết về các thao tác cần thiết của Khung nhìn Signals là quan trọng vì hai lý do; nó dùng như là một ví dụ cụ thể về cách các phần tử mô hình khác nhau làm việc cùng nhau và nó cho thấy cách bạn có thể xây dựng các khung nhìn tương tự để tương tác với Eclipse, gdb và CDI.


Kết luận

Hai đối tượng phiên (MISessionSession), hai đích (CDebugTargetTarget), và hai hệ thống phân cấp của các phần tử mô hình khác nhau hoàn toàn — hoạt động của trình gỡ rối CDT, là phức tạp đến mức mà bạn có thể tự hỏi liệu các nhà phát triển bất kỳ đã có liên quan đến Rube Goldberg không. Tuy nhiên, mã cho trình gỡ rối CDT đã được viết bằng hệ mô đun trong tâm trí, và bạn càng hiểu hoạt động bên trong của nó thì càng dễ dàng chèn vào các mô-đun riêng của bạn. Và hãy nhớ: đường học tập là khó khăn, nhưng việc thêm các tính năng mới cho CDT là dễ dàng hơn nhiều việc xây dựng một ứng dụng tùy chỉnh gỡ rối từ đầu.


Tải về

Mô tảTênKích thước
Sample codeos-eclipse-cdt-debug-ex-debugger-plugin.zip15KB

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

  • Các nhóm tin nền tảng Eclipse là bước dừng chân đầu tiên của bạn để thảo luận các câu hỏi về Eclipse. (Chọn phần này sẽ khởi chạy ứng dụng đọc tin Usenet mặc định của bạn và mở eclipse.platform).
  • Các nhóm tin Eclipse có nhiều nguồn tài nguyên cho những người đã quan tâm đến việc sử dụng và mở rộng Eclipse.
  • Tham gia vào các blog developerWorks và dành tâm trí cho cộng đồng developerWorks.

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=438503
ArticleTitle=Giao diện với trình gỡ rối CDT, Phần 2: Truy cập gdb bằng CDT Eclipse và MI (Machine Interface)
publish-date=10232009