OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [gdbtcl/] [interface.tcl] - Blame information for rev 1767

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# Interface between GDB and Insight.
2
# Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
3
#
4
# This program is free software; you can redistribute it and/or modify it
5
# under the terms of the GNU General Public License (GPL) as published by
6
# the Free Software Foundation; either version 2 of the License, or (at
7
# your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
 
14
 
15
# This variable is reserved for this module.  Ensure it is an array.
16
global gdbtk_state
17
set gdbtk_state(busyCount) 0
18
 
19
# *** DEPRECATED: Use GDBEventHandler::breakpoint instead.
20
# This is run when a breakpoint changes.  The arguments are the
21
# action, the breakpoint number, and the breakpoint info.
22
#define_hook gdb_breakpoint_change_hook
23
 
24
# *** DEPRECATED: Use GDBEventHandler::set_variable instead.
25
# This is run when a `set' command successfully completes in gdb.  The
26
# first argument is the gdb variable name (as a Tcl list).  The second
27
# argument is the new value.
28
#define_hook gdb_set_hook
29
 
30
# ------------------------------------------------------------
31
#  PROC:  gdbtk_tcl_set_variable - A "set" command was issued
32
#          in gdb to change an internal variable. Notify
33
#          gui.
34
# ------------------------------------------------------------
35
proc gdbtk_tcl_set_variable {var val} {
36
  set e [SetVariableEvent \#auto -variable $var -value $val]
37
  GDBEventHandler::dispatch $e
38
  delete object $e
39
}
40
 
41
####################################################################
42
#                                                                  #
43
#                        GUI STATE HOOKS                           #
44
#                                                                  #
45
####################################################################
46
# !!!!!   NOTE   !!!!!
47
# For debugging purposes, please put debug statements at the very
48
# beginning and ends of all GUI state hooks.
49
 
50
# *** DEPRECATED: Use GDBEventHandler::busy instead.
51
# GDB_BUSY_HOOK
52
#   This hook is used to register a callback when the UI should
53
#   be disabled because the debugger is either busy or talking
54
#   to the target.
55
#
56
#   All callbacks should disable ALL user input which could cause
57
#   any state changes in either the target or the debugger.
58
#define_hook gdb_busy_hook
59
 
60
# *** DEPRECATED: Use GDBEventHandler::idle instead.
61
# GDB_IDLE_HOOK
62
#   This hook is used to register a callback when the UI should
63
#   be enabled because the debugger is no longer busy.
64
#
65
#   All callbacks should enable user input. These callbacks
66
#   should also be as fast as possible to avoid any significant
67
#   time delays when enabling the UI.
68
define_hook gdb_idle_hook
69
 
70
# *** DEPRECATED: Use GDBEventHandler::update instead.
71
# GDB_UPDATE_HOOK
72
#   This hook is used to register a callback to update the widget
73
#   when debugger state has changed.
74
#define_hook gdb_update_hook
75
 
76
# GDB_NO_INFERIOR_HOOK
77
#   This hook is used to register a callback which should be invoked
78
#   whenever there is no inferior (either at startup time or when
79
#   an inferior is killed).
80
#
81
#   All callbacks should reset their windows to a known, "startup"
82
#   state.
83
define_hook gdb_no_inferior_hook
84
 
85
# GDB_DISPLAY_CHANGE_HOOK
86
# This is run when a display changes.  The arguments are the action,
87
# the breakpoint number, and (optionally) the value.
88
define_hook gdb_display_change_hook
89
 
90
# GDB_TRACE_FIND_HOOK
91
#    This hook is run by the trace find command.  It is used to switch
92
#    from control to browse mode when the user runs tfind commands...
93
#
94
define_hook gdb_trace_find_hook
95
 
96
# ------------------------------------------------------------------
97
#  gdbtk_tcl_preloop - This function is called after gdb is initialized
98
#  but before the mainloop is started.  It sets the app name, and
99
#  opens the first source window.
100
# ------------------------------------------------------------------
101
 
102
proc gdbtk_tcl_preloop { } {
103
  global gdb_exe_name
104
 
105
  set_baud
106
 
107
  tk appname gdbtk
108
  # If there was an error loading an executible specified on the command line
109
  # then we will have called pre_add_symbol, which would set us to busy,
110
  # but not the corresponding post_add_symbol.  Do this here just in case...
111
  after idle gdbtk_idle
112
  ManagedWin::startup
113
 
114
  SrcWin::point_to_main
115
  set msg ""
116
  catch {gdb_cmd "info files"} msg
117
  set line1 [string range $msg 0 [string first \n $msg]]
118
  if {[regexp {Symbols from "(.*)"\.} $line1 dummy name]} {
119
    set gdb_exe_name $name
120
  }
121
 
122
 
123
  gdbtk_update
124
}
125
 
126
 
127
# ------------------------------------------------------------------
128
#  PROCEDURE:  gdbtk_busy - Dispatch a busy event
129
#
130
#         Use this procedure from within GUI code to indicate that
131
#         the debugger is busy, either running the inferior or
132
#         talking to the target.
133
# ------------------------------------------------------------------
134
proc gdbtk_busy {} {
135
 
136
  set e [BusyEvent \#auto]
137
  GDBEventHandler::dispatch $e
138
  delete object $e
139
 
140
  # Force the screen to update
141
  update
142
}
143
 
144
# ------------------------------------------------------------------
145
#   PROCEDURE:  gdbtk_update - run all update hooks
146
#
147
#          Use this procedure to force all widgets to update
148
#          themselves. This hook is usually run after command
149
#          that could change target state.
150
# ------------------------------------------------------------------
151
proc gdbtk_update {} {
152
 
153
  set e [UpdateEvent \#auto]
154
  GDBEventHandler::dispatch $e
155
  delete object $e
156
 
157
  # Force the screen to update
158
  update
159
}
160
 
161
# ------------------------------------------------------------------
162
#   PROCEDURE:  gdbtk_update_safe - run all update hooks in a safe way
163
#
164
#          Use this procedure to force all widgets to update
165
#          themselves. This hook is usually run after command
166
#          that could change target state.
167
#          Like gdbtk_update but safe to be used in "after idle"
168
#          which is used in update hooks.
169
# ------------------------------------------------------------------
170
proc gdbtk_update_safe {} {
171
  global gdb_running
172
 
173
  # Fencepost: Do not update if we are running the target
174
  # We get here because script commands may have changed memory or
175
  # registers and "after idle" events registered as a consequence
176
  # If we try to update while the target is running we are doomed.
177
  if {!$gdb_running} {
178
    gdbtk_update
179
  }
180
}
181
 
182
# ------------------------------------------------------------------
183
#   PROCEDURE: gdbtk_idle - dispatch IdleEvent
184
#
185
#          Use this procedure to free the UI for more user input.
186
#          This should only be run AFTER all communication with
187
#          the target has halted, otherwise the risk of two (or
188
#          more) widgets talking to the target arises.
189
# ------------------------------------------------------------------
190
proc gdbtk_idle {} {
191
  global gdb_running
192
 
193
  # Put the unfiltered hook back in place, just in case
194
  # somebody swapped it out, and then died before they
195
  # could replace it.
196
  gdb_restore_fputs
197
 
198
  set err [catch {run_hooks gdb_idle_hook}]
199
  if {$err} {
200
    dbug E "Error running gdb_idle_hook: $::errorInfo"
201
  }
202
 
203
  set e [IdleEvent \#auto]
204
  GDBEventHandler::dispatch $e
205
  delete object $e
206
 
207
  if {!$gdb_running} {
208
    set err [catch {run_hooks gdb_no_inferior_hook} txt]
209
    if {$err} {
210
      dbug E "no_inferior_hook error: $txt"
211
    }
212
  }
213
 
214
  # Force the screen to update
215
  update
216
}
217
 
218
define_hook download_progress_hook
219
 
220
# ------------------------------------------------------------------
221
#  PROCEDURE:  gdbtk_quit_check - Ask if the user really wants to quit.
222
# ------------------------------------------------------------------
223
proc gdbtk_quit_check {} {
224
  global gdb_downloading gdb_running gdb_exe_name
225
 
226
  if {$gdb_downloading} {
227
    set msg "Downloading to target,\n really close the debugger?"
228
    if {![gdbtk_tcl_query $msg no]} {
229
      return 0
230
    }
231
  } elseif {$gdb_running} {
232
    # While we are running the inferior, gdb_cmd is fenceposted and
233
    # returns immediately. Therefore, we need to ask here. Do we need
234
    # to stop the target, too?
235
    set msg "A debugging session is active.\n"
236
    append msg "Do you still want to close the debugger?"
237
    if {![gdbtk_tcl_query $msg no]} {
238
      return 0
239
    }
240
  }
241
 
242
  return 1
243
}
244
 
245
# ------------------------------------------------------------------
246
#  PROCEDURE:  gdbtk_quit - Quit the debugger
247
#         Call this procedure anywhere the user can request to quit.
248
#         This procedure will ask all the right questions before
249
#         exiting.
250
# ------------------------------------------------------------------
251
proc gdbtk_quit {} {
252
  if {[gdbtk_quit_check]} {
253
    gdb_force_quit
254
  }
255
}
256
 
257
# ------------------------------------------------------------------
258
#  PROCEDURE:  gdbtk_cleanup - called by GDB immediately
259
#         before exiting.  Last chance to cleanup!
260
# ------------------------------------------------------------------
261
proc gdbtk_cleanup {} {
262
  global gdb_exe_name
263
 
264
  # Save the session
265
  if {$gdb_exe_name != ""} {
266
    session_save
267
  }
268
 
269
  # This is a sign that it is too late to be doing updates, etc...
270
  set ::gdb_shutting_down 1
271
 
272
  # Shutdown the window manager and save all preferences
273
  # This way a "quit" in the console window will cause
274
  # preferences to be saved.
275
  ManagedWin::shutdown
276
  pref_save
277
}
278
 
279
# ------------------------------------------------------------------
280
# PROC: gdbtk_tcl_query -
281
# ------------------------------------------------------------------
282
proc gdbtk_tcl_query {message {default yes}} {
283
  global gdb_checking_for_exit gdbtk_state tcl_platform
284
 
285
  # FIXME We really want a Help button here.  But Tk's brain-damaged
286
  # modal dialogs won't really allow it.  Should have async dialog
287
  # here.
288
 
289
  set title "GDB"
290
  set modal "task"
291
 
292
  # If we are checking whether to exit gdb, we want a system modal
293
  # box.  Otherwise it may be hidden by some other program, and the
294
  # user will have no idea what is going on.
295
  if {[info exists gdb_checking_for_exit] && $gdb_checking_for_exit} {
296
    set modal "system"
297
  }
298
 
299
  if {$tcl_platform(platform) == "windows"} {
300
    # On Windows, we want to only ask each question once.
301
    # If we're already asking the question, just wait for the answer
302
    # to come back.
303
    set ans [list answer $message]
304
    set pending [list pending $message]
305
 
306
    if {[info exists gdbtk_state($pending)]} {
307
      incr gdbtk_state($pending)
308
    } else {
309
      set gdbtk_state($pending) 1
310
      set gdbtk_state($ans) {}
311
 
312
      ide_messageBox [list set gdbtk_state($ans)] -icon warning \
313
        -default $default -message $message -title $title \
314
        -type yesno -modal $modal -parent .
315
    }
316
 
317
    vwait gdbtk_state($ans)
318
    set r $gdbtk_state($ans)
319
    if {[incr gdbtk_state($pending) -1] == 0} {
320
      # Last call waiting for this answer, so clear it.
321
      unset gdbtk_state($pending)
322
      unset gdbtk_state($ans)
323
    }
324
  } else {
325
    # On Unix, apparently it doesn't matter how many times we ask a
326
    # question.
327
    set r [tk_messageBox -icon warning -default $default \
328
             -message $message -title $title \
329
             -type yesno -modal $modal -parent .]
330
  }
331
 
332
  update idletasks
333
  return [expr {$r == "yes"}]
334
}
335
 
336
# ------------------------------------------------------------------
337
# PROC: gdbtk_tcl_warning -
338
# ------------------------------------------------------------------
339
proc gdbtk_tcl_warning {message} {
340
  debug "$message"
341
 
342
# ADD a warning message here if the gui must NOT display it
343
# add the message at the beginning of the switch followed by - 
344
 
345
  switch -regexp $message {
346
        "Unable to find dynamic linker breakpoint function.*" {return}
347
        default {show_warning $message}
348
       }
349
}
350
 
351
# ------------------------------------------------------------------
352
# PROC: show_warning -
353
# ------------------------------------------------------------------
354
proc show_warning {message} {
355
  global tcl_platform
356
 
357
  # FIXME We really want a Help button here.  But Tk's brain-damaged
358
  # modal dialogs won't really allow it.  Should have async dialog
359
  # here.
360
  set title "GDB"
361
  set modal "task"
362
 
363
# On Windows, we use ide_messageBox which runs the Win32 MessageBox function
364
# in another thread.  This permits a program which handles IDE requests from
365
# other programs to not return from the request until the MessageBox completes.
366
# This is not possible without using another thread, since the MessageBox
367
# function call will be running its own event loop, and will be higher on the
368
# stack than the IDE request.
369
#
370
# On Unix tk_messageBox runs in the regular Tk event loop, so
371
# another thread is not required.
372
 
373
 
374
  if {$tcl_platform(platform) == "windows"} {
375
      ide_messageBox [list set r] -icon warning \
376
        -default ok -message $message -title $title \
377
        -type ok -modal $modal -parent .
378
  } else {
379
    set r [tk_messageBox -icon warning -default ok \
380
             -message $message -title $title \
381
             -type ok -modal $modal -parent .]
382
  }
383
}
384
 
385
# ------------------------------------------------------------------
386
# PROC: gdbtk_tcl_ignorable_warning -
387
# ------------------------------------------------------------------
388
proc gdbtk_tcl_ignorable_warning {class message} {
389
  catch {ManagedWin::open WarningDlg -center -transient \
390
           -message [list $message] -ignorable $class}
391
}
392
 
393
# ------------------------------------------------------------------
394
# PROC: gdbtk_tcl_fputs -
395
# ------------------------------------------------------------------
396
proc gdbtk_tcl_fputs {message} {
397
  global gdbtk_state
398
  # Restore the fputs hook, in case anyone forgot to put it back...
399
  gdb_restore_fputs
400
 
401
  if {$gdbtk_state(console) != ""} {
402
    $gdbtk_state(console) insert $message
403
  }
404
}
405
 
406
# ------------------------------------------------------------------
407
# PROC: echo -
408
# ------------------------------------------------------------------
409
proc echo {args} {
410
  gdbtk_tcl_fputs [concat $args]\n
411
}
412
 
413
# ------------------------------------------------------------------
414
# PROC: gdbtk_tcl_fputs_error - write an error message
415
# ------------------------------------------------------------------
416
proc gdbtk_tcl_fputs_error {message} {
417
  if {$::gdbtk_state(console) != ""} {
418
    $::gdbtk_state(console) einsert $message err_tag
419
    update
420
  }
421
}
422
 
423
# ------------------------------------------------------------------
424
# PROC: gdbtk_tcl_fputs_log - write a log message
425
# ------------------------------------------------------------------
426
proc gdbtk_tcl_fputs_log {message} {
427
  if {$::gdbtk_state(console) != ""} {
428
    $::gdbtk_state(console) einsert $message log_tag
429
    update
430
  }
431
}
432
 
433
# ------------------------------------------------------------------
434
# PROC: gdbtk_tcl_fputs_target - write target output
435
# ------------------------------------------------------------------
436
proc gdbtk_tcl_fputs_target {message} {
437
  if {$::gdbtk_state(console) != ""} {
438
    $::gdbtk_state(console) einsert $message target_tag
439
    update
440
  }
441
}
442
 
443
# ------------------------------------------------------------------
444
# PROC: gdbtk_tcl_flush -
445
# ------------------------------------------------------------------
446
proc gdbtk_tcl_flush {} {
447
  debug [info level 0]
448
}
449
 
450
# ------------------------------------------------------------------
451
# PROC: gdbtk_tcl_start_variable_annotation -
452
# ------------------------------------------------------------------
453
proc gdbtk_tcl_start_variable_annotation {valaddr ref_type stor_cl
454
                                          cum_expr field type_cast} {
455
  debug [info level 0]
456
}
457
 
458
# ------------------------------------------------------------------
459
# PROC: gdbtk_tcl_end_variable_annotation -
460
# ------------------------------------------------------------------
461
proc gdbtk_tcl_end_variable_annotation {} {
462
  debug [info level 0]
463
}
464
 
465
# ------------------------------------------------------------------
466
# PROC: gdbtk_tcl_breakpoint - A breakpoint was changed -- notify
467
#                               gui.
468
# ------------------------------------------------------------------
469
proc gdbtk_tcl_breakpoint {action bpnum} {
470
#  debug "BREAKPOINT: $action $bpnum"
471
  set e [BreakpointEvent \#auto -action $action -number $bpnum]
472
  GDBEventHandler::dispatch $e
473
  delete object $e
474
}
475
 
476
# ------------------------------------------------------------------
477
# PROC: gdbtk_tcl_tracepoint - A tracepoint was changed -- notify
478
#                               gui.
479
# ------------------------------------------------------------------
480
proc gdbtk_tcl_tracepoint {action tpnum} {
481
#  debug "TRACEPOINT: $action $tpnum"
482
  set e [TracepointEvent \#auto -action $action -number $tpnum]
483
  GDBEventHandler::dispatch $e
484
  delete object $e
485
}
486
 
487
# ------------------------------------------------------------------
488
# PROC: gdbtk_tcl_trace_find_hook -
489
# ------------------------------------------------------------------
490
proc gdbtk_tcl_trace_find_hook {arg from_tty} {
491
#  debug "$arg $from_tty"
492
  run_hooks gdb_trace_find_hook $arg $from_tty
493
}
494
 
495
################################################################
496
#
497
# Handle `readline' interface.
498
#
499
 
500
# Run a command that is known to use the "readline" interface.  We set
501
# up the appropriate buffer, and then run the actual command via
502
# gdb_cmd.  Calls into the "readline" callbacks just return values
503
# from our list.
504
 
505
# ------------------------------------------------------------------
506
# PROC: gdb_run_readline_command -
507
# ------------------------------------------------------------------
508
proc gdb_run_readline_command {command args} {
509
  global gdbtk_state
510
#  debug "$command $args"
511
  set gdbtk_state(readlineArgs) $args
512
  gdb_cmd $command
513
}
514
 
515
# ------------------------------------------------------------------
516
# PROC: gdbtk_tcl_readline_begin -
517
# ------------------------------------------------------------------
518
proc gdbtk_tcl_readline_begin {message} {
519
  global gdbtk_state
520
#  debug "readline begin"
521
  set gdbtk_state(readline) 0
522
  if {$gdbtk_state(console) != ""} {
523
    $gdbtk_state(console) insert $message
524
  }
525
}
526
 
527
# ------------------------------------------------------------------
528
# PROC: gdbtk_tcl_readline -
529
# ------------------------------------------------------------------
530
proc gdbtk_tcl_readline {prompt} {
531
  global gdbtk_state
532
#  debug "$prompt"
533
  if {[info exists gdbtk_state(readlineArgs)]} {
534
    # Not interactive, so pop the list, and print element.
535
    set cmd [lvarpop gdbtk_state(readlineArgs)]
536
    command::insert_command $cmd
537
  } else {
538
    # Interactive.
539
#    debug "interactive"
540
    set gdbtk_state(readline) 1
541
    $gdbtk_state(console) activate $prompt
542
    vwait gdbtk_state(readline_response)
543
    set cmd $gdbtk_state(readline_response)
544
#    debug "got response: $cmd"
545
    unset gdbtk_state(readline_response)
546
    set gdbtk_state(readline) 0
547
  }
548
  return $cmd
549
}
550
 
551
# ------------------------------------------------------------------
552
# PROC: gdbtk_tcl_readline_end -
553
# ------------------------------------------------------------------
554
proc gdbtk_tcl_readline_end {} {
555
  global gdbtk_state
556
#  debug "readline_end"
557
  catch {unset gdbtk_state(readlineArgs)}
558
  unset gdbtk_state(readlineActive)
559
  command::end_multi_line_input
560
}
561
 
562
# ------------------------------------------------------------------
563
# PROC: gdbtk_tcl_busy - this is called immediately before gdb 
564
#    executes a command.
565
#
566
# ------------------------------------------------------------------
567
proc gdbtk_tcl_busy {} {
568
  global gdbtk_state
569
  if {[incr gdbtk_state(busyCount)] == 1} {
570
    gdbtk_busy
571
  }
572
}
573
 
574
################################################################
575
#
576
# 
577
#
578
 
579
# ------------------------------------------------------------------
580
# PROC: gdbtk_tcl_idle - this is called immediately after gdb 
581
#    executes a command.
582
# ------------------------------------------------------------------
583
proc gdbtk_tcl_idle {} {
584
  global gdbtk_state
585
  if {$gdbtk_state(busyCount) > 0
586
      && [incr gdbtk_state(busyCount) -1] == 0} {
587
    gdbtk_update
588
    gdbtk_idle
589
  }
590
}
591
 
592
# ------------------------------------------------------------------
593
# PROC: gdbtk_tcl_tstart -
594
# ------------------------------------------------------------------
595
proc gdbtk_tcl_tstart {} {
596
  set srcwin [lindex [manage find src] 0]
597
  $srcwin.toolbar do_tstop 0
598
 
599
}
600
 
601
# ------------------------------------------------------------------
602
# PROC: gdbtk_tcl_tstop -
603
# ------------------------------------------------------------------
604
proc gdbtk_tcl_tstop {} {
605
  set srcwin [lindex [manage find src] 0]
606
  $srcwin.toolbar do_tstop 0
607
 
608
}
609
 
610
 
611
# ------------------------------------------------------------------
612
# PROC: gdbtk_tcl_display -
613
#
614
# A display changed.  ACTION is `enable', `disable', `delete',
615
# `create', or `update'.  VALUE is only meaningful in the `update'
616
# case.
617
# ------------------------------------------------------------------
618
proc gdbtk_tcl_display {action number {value {}}} {
619
  # Handle create explicitly.
620
  if {$action == "create"} {
621
    manage create_if_never data
622
  }
623
  run_hooks gdb_display_change_hook $action $number $value
624
}
625
 
626
# ------------------------------------------------------------------
627
#  PROCEDURE: gdbtk_register_changed
628
#         This hook is called from value_assign to inform us that
629
#         the user has changed the contents of a register.
630
# ------------------------------------------------------------------
631
proc gdbtk_register_changed {} {
632
  after idle gdbtk_update_safe
633
}
634
 
635
# ------------------------------------------------------------------
636
#  PROCEDURE: gdbtk_memory_changed
637
#         This hook is called from value_assign to inform us that
638
#         the user has changed the contents of memory (including
639
#         the program's variables).
640
# ------------------------------------------------------------------
641
proc gdbtk_memory_changed {} {
642
  after idle gdbtk_update_safe
643
}
644
 
645
####################################################################
646
#                                                                  #
647
#                           FILE HOOKS                             #
648
#                                                                  #
649
#    There are a number of hooks that are installed in gdb to      #
650
#    aid with file-like commands (selecting an exectuable and      #
651
#    loading symbols):                                             #
652
#         - exec_file_display_hook                                 #
653
#            Called in exec_file_command. The tcl hook is          #
654
#            "gdbtk_tcl_exec_file_display"                         #
655
#         - file_changed_hook                                      #
656
#            Called in file_command. The tcl hook is               #
657
#            "gdbtk_tcl_file_changed"                              #
658
#         - pre_add_symbol_hook                                    #
659
#            Called in symbol_file_add before loading. The tcl     #
660
#            hook is "gdbtk_tcl_pre_add_symbol"                    #
661
#         - post_add_symbol_hook                                   #
662
#            Called in symbol_file_add when finished loading       #
663
#            a symbol file. The tcl hook is                        #
664
#            "gdbtk_tcl_post_add_symbol"                           #
665
#                                                                  #
666
#  Together, these hooks should give the gui enough information    #
667
#  to cover the two most common uses of file commands:             #
668
#  1. executable with symbols                                      #
669
#  2. separate executable and symbol file(s)                       #
670
#                                                                  #
671
####################################################################
672
define_hook file_changed_hook
673
 
674
# ------------------------------------------------------------------
675
#  PROCEDURE:  gdbtk_tcl_pre_add_symbol
676
#         This hook is called before any symbol files
677
#         are loaded so that we can inform the user.
678
# ------------------------------------------------------------------
679
proc gdbtk_tcl_pre_add_symbol {file} {
680
 
681
  gdbtk_busy
682
 
683
  # Display some feedback to the user
684
  set srcs [ManagedWin::find SrcWin]
685
  foreach w $srcs {
686
    $w set_status "Reading symbols from $file..."
687
  }
688
  update idletasks
689
}
690
 
691
# ------------------------------------------------------------------
692
#   PROCEDURE: gdbtk_tcl_post_add_symbol
693
#          This hook is called after we finish reading a symbol
694
#          file, so the source windows' combo boxes need filling.
695
# ------------------------------------------------------------------
696
proc gdbtk_tcl_post_add_symbol {} {
697
 
698
  set srcs [ManagedWin::find SrcWin]
699
  foreach w $srcs {
700
    $w fillNameCB
701
  }
702
  gdbtk_idle
703
}
704
 
705
# ------------------------------------------------------------------
706
#  PROCEDURE: gdbtk_tcl_file_changed
707
#         This hook is called whenever the exec file changes.
708
#         This is called AFTER symbol reading, so it is
709
#         ok to point to main when we get called.
710
# ------------------------------------------------------------------
711
proc gdbtk_tcl_file_changed {filename} {
712
 
713
  if {$filename == ""} {
714
    gdb_clear_file
715
    run_hooks gdb_clear_file_hook
716
    set ::gdb_exe_name ""
717
    set ::gdb_loaded 0
718
    set ::gdb_running 0
719
    gdbtk_update
720
  } else {
721
    SrcWin::point_to_main
722
    run_hooks file_changed_hook
723
  }
724
}
725
 
726
# ------------------------------------------------------------------
727
#  PROCEDURE: gdbtk_tcl_exec_file_display 
728
#         This hook is called from exec_file_command. It's purpose
729
#         is to setup the gui for a new file. Note that we cannot
730
#         look for main, since this hook is called BEFORE we
731
#         read symbols. If the user used the "file" command,
732
#         gdbtk_tcl_file_changed will set the source window to
733
#         look at main. If the user used "exec-file" and "add-symbol"
734
#         commands, then we cannot look for main.
735
# ------------------------------------------------------------------
736
proc gdbtk_tcl_exec_file_display {filename} {
737
  global gdb_exe_changed
738
 
739
  # DO NOT CALL set_exe here! 
740
 
741
  # Clear out the GUI, don't do it if filename is "" so that
742
  # you avoid distracting flashes in the source window.
743
 
744
  if {$filename != ""} {
745
    gdbtk_clear_file
746
  }
747
 
748
  # set_exe calls file command with the filename in
749
  # quotes, so we need to strip them here.
750
  # We need to make sure that we turn filename into
751
  # an absolute path or sessions won't work.
752
  set filename [string trim $filename \']
753
  if {[string index $filename 0] != "/"} {
754
    set pwd [pwd]
755
    set filename "$pwd/$filename"
756
  }
757
  set_exe_name $filename
758
  set gdb_exe_changed 0
759
 
760
  SrcWin::point_to_main
761
}
762
 
763
# ------------------------------------------------------------------
764
#  PROCEDURE: gdbtk_locate_main
765
#         This proc tries to locate a suitable main function from
766
#         a list of names defined in the gdb/main_names preference;
767
#         returns the linespec (see below) if found, or a null string
768
#         if not.
769
#
770
#  The return linespec looks like this:
771
#  0: basename of the file
772
#  1: function name
773
#  2: full filename
774
#  3: source line number
775
#  4: address
776
#  5: current PC - which will often be the same as address, but not when
777
#  6: shared library name if the pc is in a shared lib
778
#  we are browsing, or walking the stack.
779
#
780
# ------------------------------------------------------------------
781
proc gdbtk_locate_main {} {
782
  set main_names [pref get gdb/main_names]
783
  debug "Searching $main_names"
784
  foreach main $main_names {
785
    if {![catch {gdb_search functions $main -static 1}] \
786
        && ![catch {gdb_loc $main} linespec]} {
787
      return $linespec
788
    }
789
  }
790
  if {![catch gdb_entry_point entry_point]
791
      && ![catch {gdb_loc "*$entry_point"} linespec]} {
792
    return $linespec
793
  }
794
  return {}
795
}
796
 
797
##############################################
798
#  The rest of this file is an assortment of Tcl wrappers
799
#  for various bits of gdb functionality.
800
#
801
#############################################
802
 
803
# ------------------------------------------------------------------
804
# PROC: set_exe_name - Update the executable name
805
# ------------------------------------------------------------------
806
proc set_exe_name {exe} {
807
  global gdb_exe_name gdb_exe_changed
808
  #debug "exe=$exe  gdb_exe_name=$gdb_exe_name"
809
 
810
  if {$gdb_exe_name != ""} then {
811
    session_save
812
  }
813
 
814
  set gdb_exe_name $exe
815
  set gdb_exe_changed 1
816
}
817
 
818
 
819
# ------------------------------------------------------------------
820
# PROC: set_exe -
821
# ------------------------------------------------------------------
822
proc set_exe {} {
823
  global gdb_exe_name gdb_exe_changed gdb_target_changed gdb_loaded file_done
824
#  debug "gdb_exe_changed=$gdb_exe_changed gdb_exe_name=$gdb_exe_name"
825
  if {$gdb_exe_changed} {
826
    set gdb_exe_changed 0
827
    if {$gdb_exe_name == ""} { return }
828
    set err [catch {gdb_cmd "file '$gdb_exe_name'" 1} msg]
829
    if {$err} {
830
      dbug E "$msg"
831
      set l [split $msg :]
832
      set errtxt [join [lrange $l 1 end] :]
833
      set msg "Error loading \"$gdb_exe_name\":\n"
834
      append msg $errtxt
835
      tk_messageBox -title "Error" -message $msg -icon error \
836
        -type ok
837
      set gdb_exe_name {}
838
      set file_done 0
839
      return
840
    } elseif {[string match {*no debugging symbols found*} $msg]} {
841
      tk_messageBox -icon error -default ok \
842
        -title "GDB" -type ok -modal system \
843
        -message "This executable has no debugging information."
844
      set gdb_exe_name {}
845
      set file_done 0
846
      return
847
    }
848
 
849
    # force new target command
850
    set gdb_target_changed 1
851
    set gdb_loaded 0
852
    set file_done 1
853
  }
854
}
855
 
856
# ------------------------------------------------------------------
857
#  _open_file - open a file dialog to select a file for debugging.
858
#  If filename is not "", then open this file.
859
# ------------------------------------------------------------------
860
 
861
proc _open_file {{file ""}} {
862
  global gdb_running gdb_downloading tcl_platform
863
 
864
  if {$gdb_running || $gdb_downloading} {
865
    # We are already running/downloading something..
866
    if {$gdb_running} {
867
      set msg "A debugging session is active.\nAbort session and load new file?"
868
    } else {
869
      set msg "A download is in progress.\nAbort download and load new file?"
870
    }
871
    if {![gdbtk_tcl_query $msg no]} {
872
      return 0
873
    }
874
  }
875
 
876
  if {[string compare $file ""] == 0} {
877
    set curFocus [focus]
878
 
879
    # Make sure that this is really a modal dialog...
880
    # FIXME: Add a disable_all to ide_grab_support.
881
 
882
    ide_grab_support disable_except {}
883
 
884
    set file [tk_getOpenFile -parent . -title "Load New Executable"]
885
 
886
    ide_grab_support enable_all
887
 
888
    # If no one had the focus before, leave it that way (since I
889
    # am not sure how this could happen...  Also, the vwait in
890
    # tk_getOpenFile could have allowed the curFocus window to actually
891
    # be destroyed, so make sure it is still around.
892
 
893
    if {$curFocus != "" && [winfo exists $curFocus]} {
894
      raise [winfo toplevel $curFocus]
895
      focus $curFocus
896
    }
897
  } elseif {![file exists $file]} {
898
    tk_messageBox -message "File \"$file\" does not exist"
899
    return 0
900
  }
901
 
902
 
903
  if {$file == ""} {
904
    return 0
905
  }
906
  # Add the base dir for this file to the source search path.
907
  set root [file dirname $file]
908
  if {$tcl_platform(platform) == "windows"} {
909
    set root [ide_cygwin_path to_posix $root]
910
    set file [ide_cygwin_path to_posix $file]
911
  }
912
 
913
  catch {gdb_cmd "cd $root"}
914
 
915
  # Clear out gdb's internal state, so that it will allow us
916
  # (the gui) to ask the user questions.
917
  gdb_clear_file
918
 
919
  # The gui needs to set this...
920
  set_exe_name $file
921
 
922
  # set_exe needs to be called anywhere the gui does a file_command...
923
  if {[set_exe] == "cancel"} {
924
    gdbtk_update
925
    gdbtk_idle
926
    return 0
927
  }
928
 
929
  return 1
930
}
931
 
932
# ------------------------------------------------------------------
933
#  _close_file - close the current executable and prepare for
934
#    another executable.
935
# ------------------------------------------------------------------
936
proc _close_file {} {
937
 
938
  # If there is already an inferior, ask him if he wants to close
939
  # the file. If there is already an exec file loaded (and not run)
940
  # also ask, but don't ask twice.
941
  set okay 1
942
  if {[gdb_target_has_execution]} {
943
    set okay [gdbtk_tcl_query "Program is already running.\nClose file anyway?"]
944
  } elseif {$::gdb_exe_name != ""} {
945
    set okay [gdbtk_tcl_query "Program already loaded.\nClose file anyway?"]
946
  } else {
947
    # No exec file yet
948
    return
949
  }
950
 
951
  if {$okay} {
952
    gdb_clear_file
953
    gdbtk_tcl_file_changed ""
954
 
955
    # Print out a little message to all console windows
956
    foreach cw [ManagedWin::find Console] {
957
      $cw insert "No executable file now.\n"
958
    }
959
  }
960
}
961
 
962
# ------------------------------------------------------------------
963
# PROC: set_target_name - Update the target name.  
964
#
965
# This function will prompt for a new target and update
966
# all variables.
967
#
968
# If $prompt is 0 it will just update gdb_target_cmd from gdb_target.
969
#
970
# RETURN:
971
#     1 if successful, 
972
#     0 if the not (the user canceled the target selection dialog)
973
# ------------------------------------------------------------------
974
proc set_target_name {{prompt 1}} {
975
  global gdb_target_name gdb_target_changed gdb_exe_changed
976
  global gdb_target_cmd gdb_pretty_name
977
#  debug
978
  set cmd_tmp $gdb_target_cmd
979
  set name_tmp $gdb_target_name
980
 
981
#  debug "gdb_target_name=$gdb_target_name; name_tmp=$name_tmp"
982
  if {$prompt} {
983
    set win [ManagedWin::open TargetSelection -exportcancel 1 -center \
984
               -transient]
985
    # need to call update here so the target selection dialog can take over
986
    update idletasks
987
  }
988
 
989
#  debug "gdb_target_name=$gdb_target_name"
990
  if {$gdb_target_name == "CANCEL"} {
991
    set gdb_target_cmd $cmd_tmp
992
    set gdb_target_name $name_tmp
993
    return 0
994
  }
995
  set target $gdb_target_name
996
  set targ [TargetSelection::getname $target cmd]
997
  set gdb_target_cmd $cmd_tmp
998
  set gdb_pretty_name [TargetSelection::getname $target pretty-name]
999
 
1000
#  debug "target=$target pretty_name=$gdb_pretty_name"
1001
  set targ_opts ""
1002
  switch -regexp -- $gdb_target_name {
1003
    sim|ice {
1004
      set targ $gdb_target_name
1005
      set targ_opts [pref getd gdb/load/${gdb_target_name}-opts]
1006
    }
1007
    default {
1008
      set port [pref getd gdb/load/$target-port]
1009
      if {$port == ""} {
1010
        set port [pref get gdb/load/default-port]
1011
      }
1012
      set portnum [pref getd gdb/load/$target-portname]
1013
      if {$portnum == ""} {
1014
        set portnum [pref get gdb/load/default-portname]
1015
      }
1016
      set hostname [pref getd gdb/load/$target-hostname]
1017
      if {$hostname == ""} {
1018
        set hostname [pref get gdb/load/default-hostname]
1019
      }
1020
      # replace "com1" with the real port name
1021
      set targ [lrep $targ "com1" $port]
1022
      # replace "tcpX" with hostname:portnum
1023
      set targ [lrep $targ "tcpX" ${hostname}:${portnum}]
1024
      # replace "ethX" with hostname
1025
      set targ [lrep $targ "ethX" e=${hostname}]
1026
    }
1027
  }
1028
 
1029
#  debug "targ=$targ gdb_target_cmd=$gdb_target_cmd"
1030
  if {$gdb_target_cmd != $targ || $gdb_target_changed} {
1031
    set gdb_target_changed 1
1032
    set gdb_target_cmd "$targ $targ_opts"
1033
  }
1034
  return 1
1035
}
1036
 
1037
# ------------------------------------------------------------------
1038
# PROC: set_target - Change the target
1039
# ------------------------------------------------------------------
1040
proc set_target {} {
1041
  global gdb_target_cmd gdb_target_changed gdb_pretty_name gdb_target_name
1042
#  debug "gdb_target_changed=$gdb_target_changed gdb_target_cmd=\"$gdb_target_cmd\""
1043
#  debug "gdb_target_name=$gdb_target_name"
1044
  if {$gdb_target_cmd == "" && ![TargetSelection::native_debugging]} {
1045
    if {$gdb_target_name == ""} {
1046
      set prompt 1
1047
 
1048
      # get the default
1049
      #set gdb_target_name [pref getd gdb/load/target]
1050
    } else {
1051
      set prompt 0
1052
    }
1053
    if {![set_target_name $prompt]} {
1054
      set gdb_target_name ""
1055
      return CANCELED
1056
    }
1057
  }
1058
 
1059
  if {$gdb_target_changed} {
1060
    set srcWin [lindex [ManagedWin::find SrcWin] 0]
1061
 
1062
    $srcWin set_status "Trying to communicate with target $gdb_pretty_name" 1
1063
    update
1064
    catch {gdb_cmd "detach"}
1065
    debug "CONNECTING TO TARGET: $gdb_target_cmd"
1066
    set err [catch {gdb_immediate "target $gdb_target_cmd"} msg ]
1067
    $srcWin set_status
1068
 
1069
    if {$err} {
1070
      if {[string first "Program not killed" $msg] != -1} {
1071
        return CANCELED
1072
      }
1073
      update
1074
      set dialog_title "GDB"
1075
      set debugger_name "GDB"
1076
      tk_messageBox -icon error -title $dialog_title -type ok \
1077
        -modal task -message "$msg\n\n$debugger_name cannot connect to the target board\
1078
using [lindex $gdb_target_cmd 1].\nVerify that the board is securely connected and, if\
1079
necessary,\nmodify the port setting with the debugger preferences."
1080
      return ERROR
1081
    }
1082
 
1083
    if {![catch {pref get gdb/load/$gdb_target_name-after_attaching} aa] && $aa != ""} {
1084
      if {[catch {gdb_cmd $aa} err]} {
1085
        catch {[ManagedWin::find Console] einsert $err err_tag}
1086
      }
1087
    }
1088
    set gdb_target_changed 0
1089
    return TARGET_CHANGED
1090
  }
1091
  return TARGET_UNCHANGED
1092
}
1093
 
1094
# ------------------------------------------------------------------
1095
# PROC: run_executable -
1096
#
1097
# This procedure is used to run an executable.  It is called when the 
1098
# run button is used.
1099
# ------------------------------------------------------------------
1100
proc run_executable { {auto_start 1} } {
1101
  global gdb_loaded gdb_downloading gdb_target_name
1102
  global gdb_exe_changed gdb_target_changed gdb_program_has_run
1103
  global gdb_running gdb_exe_name tcl_platform
1104
 
1105
#  debug "auto_start=$auto_start gdb_target_name=$gdb_target_name"
1106
 
1107
  set gdb_running_saved $gdb_running
1108
  set gdb_running 0
1109
 
1110
  # No executable was specified.  Prompt the user for one.
1111
  if {$gdb_exe_name == ""} {
1112
    if {[_open_file]} {
1113
      run_executable $auto_start
1114
      return
1115
    } else {
1116
      # The user canceled the load of a new executable.
1117
      return
1118
    }
1119
  }
1120
 
1121
  if {$gdb_downloading} { return }
1122
  if {[pref get gdb/control_target]} {
1123
    # Breakpoint mode
1124
    set_exe
1125
 
1126
    # Attach
1127
    if {$gdb_target_name == "" || [pref get gdb/src/run_attach]} {
1128
      if {[gdbtk_attach_remote] == "ATTACH_CANCELED"} {
1129
        return
1130
      }
1131
    }
1132
 
1133
    # Download
1134
    if {[pref get gdb/src/run_load] && $gdb_target_name != "exec"} {
1135
      debug "Downloading..."
1136
      set gdb_loaded 0
1137
 
1138
      # if the app has not been downloaded or the app has already
1139
      # started, we need to redownload before running
1140
      if {!$gdb_loaded} {
1141
        if {[Download::download_it]} {
1142
          # user cancelled the command
1143
#         debug "user cancelled the command $gdb_running"
1144
          set gdb_loaded 0
1145
          gdbtk_update
1146
          gdbtk_idle
1147
        }
1148
        if {!$gdb_loaded} {
1149
          # The user cancelled the download after it started
1150
#         debug "User cancelled the download after it started $gdb_running"
1151
          gdbtk_update
1152
          gdbtk_idle
1153
          return
1154
        }
1155
      }
1156
    }
1157
 
1158
    # _Now_ set/clear breakpoints
1159
    if {[pref get gdb/load/exit] && ![TargetSelection::native_debugging]} {
1160
      debug "Setting new BP at exit"
1161
      catch {gdb_cmd "clear exit"}
1162
      catch {gdb_cmd "break exit"}
1163
    }
1164
 
1165
    if {[pref get gdb/load/main]} {
1166
      set main "main"
1167
      if {[set linespec [gdbtk_locate_main]] != ""} {
1168
        set main [lindex $linespec 1]
1169
      }
1170
      debug "Setting new BP at $main"
1171
      catch {gdb_cmd "clear $main"}
1172
      catch {gdb_cmd "break $main"}
1173
    }
1174
 
1175
    # set BP at user-specified function
1176
    if {[pref get gdb/load/bp_at_func]} {
1177
      foreach bp [pref get gdb/load/bp_func] {
1178
        debug "Setting BP at $bp"
1179
        catch {gdb_cmd "clear $bp"}
1180
        catch {gdb_cmd "break $bp"}
1181
      }
1182
    }
1183
 
1184
    # This is a hack.  If the target is "sim" the opts are appended
1185
    # to the target command. Otherwise they are assumed to be command line
1186
    # args.  What about simulators that accept command line args?
1187
    if {$gdb_target_name != "sim"} {
1188
      # set args
1189
      set gdb_args [pref getd gdb/load/$gdb_target_name-opts]
1190
      if { $gdb_args != ""} {
1191
        debug "set args $gdb_args"
1192
        gdb_set_inferior_args $gdb_args
1193
      }
1194
    }
1195
 
1196
    # If the user requested it, start an xterm for use as the
1197
    # inferior's tty.
1198
    if {$tcl_platform(platform) != "windows"
1199
        && [pref getd gdb/process/xtermtty] == "yes"} {
1200
      tty::create
1201
    }
1202
 
1203
    # 
1204
    # Run
1205
 
1206
    if {$auto_start} {
1207
      if {[pref get gdb/src/run_run]} {
1208
        debug "Runnning target..."
1209
        set run run
1210
      } else {
1211
        debug "Continuing target..."
1212
        set run cont
1213
      }
1214
      if {$gdb_target_name == "exec"} {
1215
        set run run
1216
      }
1217
      if {[catch {gdb_immediate $run} msg]} {
1218
        dbug W "msg=$msg"
1219
        gdbtk_idle
1220
        if {[string match "*help target*" $msg]} {
1221
          set_target_name
1222
          run_executable $auto_start
1223
          return
1224
        }
1225
        if {[string match "No executable*" $msg]} {
1226
          # No executable was specified.  Prompt the user for one.
1227
          if {[_open_file]} {
1228
            run_executable $auto_start
1229
          } else {
1230
            debug "CANCELLED"
1231
          }
1232
          return
1233
        }
1234
        set gdb_running $gdb_running_saved
1235
      } else {
1236
        debug RUNNING
1237
        set gdb_running 1
1238
      }
1239
    } else {
1240
      SrcWin::point_to_main
1241
    }
1242
 
1243
    gdbtk_update
1244
    gdbtk_idle
1245
  } elseif {[pref get gdb/mode]} {
1246
    # tracepoint -- need to tstart
1247
    set gdb_running 1
1248
    tstart
1249
  }
1250
  return
1251
}
1252
 
1253
# ------------------------------------------------------------------
1254
#  PROC: gdbtk_attach_remote - attach to the target
1255
#        This proc returns the following status messages:
1256
#
1257
#        ATTACH_ERROR: An error occurred connecting to target.
1258
#        ATTACH_CANCELED: The attach was canceled.
1259
#        ATTACH_TARGET_CHANGED: Successfully attached, target changed.
1260
#        ATTACH_TARGET_UNCHANGED: Successfully attached, target unchanged.
1261
#        UNKNOWN: An unknown error occurred.
1262
# ------------------------------------------------------------------
1263
proc gdbtk_attach_remote {} {
1264
  global gdb_loaded
1265
 
1266
  debug "Attaching...."
1267
  set r UNKNOWN
1268
  while {1} {
1269
 
1270
    switch [set_target] {
1271
 
1272
      ERROR {
1273
        # target command failed, ask for a new target name
1274
        if {![set_target_name]} {
1275
          # canceled again
1276
          set r ATTACH_ERROR
1277
          break
1278
        }
1279
      }
1280
 
1281
      TARGET_CHANGED {
1282
        # success -- target changed
1283
        set gdb_loaded 0
1284
        set r ATTACH_TARGET_CHANGED
1285
        break
1286
      }
1287
 
1288
      CANCELED {
1289
        # command cancelled by user
1290
        set r ATTACH_CANCELED
1291
        break
1292
      }
1293
 
1294
      TARGET_UNCHANGED {
1295
        # success -- target NOT changed (i.e., rerun)
1296
        set r ATTACH_TARGET_UNCHANGED
1297
        break
1298
      }
1299
    }
1300
  }
1301
 
1302
#  debug "Attach returning: \"$r\""
1303
  return $r
1304
}
1305
 
1306
# ------------------------------------------------------------------
1307
# PROC:  gdbtk_connect: connect to a remote target 
1308
#                      in asynch mode if async is 1
1309
# ------------------------------------------------------------------
1310
proc gdbtk_connect {{async 0}} {
1311
  global file_done
1312
 
1313
  debug "async=$async"
1314
 
1315
  gdbtk_busy
1316
 
1317
  set result [gdbtk_attach_remote]
1318
  switch $result {
1319
    ATTACH_ERROR {
1320
      set successful 0
1321
    }
1322
 
1323
    ATTACH_TARGET_CHANGED {
1324
        if {[pref get gdb/load/check] && $file_done} {
1325
          set err [catch {gdb_cmd "compare-sections"} errTxt]
1326
          if {$err} {
1327
            set successful 0
1328
            tk_messageBox -title "Error" -message $errTxt \
1329
              -icon error -type ok
1330
            break
1331
          }
1332
        }
1333
 
1334
        tk_messageBox -title "GDB" -message "Successfully connected" \
1335
          -icon info -type ok
1336
        set successful 1
1337
    }
1338
 
1339
    ATTACH_CANCELED {
1340
        tk_messageBox -title "GDB" -message "Connection Canceled" -icon info \
1341
          -type ok
1342
        set successful 0
1343
    }
1344
 
1345
    ATTACH_TARGET_UNCHANGED {
1346
        tk_messageBox -title "GDB" -message "Successfully connected" \
1347
          -icon info -type ok
1348
        set successful 1
1349
    }
1350
 
1351
    default {
1352
        dbug E "Unhandled response from gdbtk_attach_remote: \"$result\""
1353
        set successful 0
1354
    }
1355
  }
1356
 
1357
  gdbtk_idle
1358
 
1359
  # Whenever we attach, we need to do an update
1360
  if {$successful} {
1361
    gdbtk_attached
1362
  }
1363
  return $successful
1364
}
1365
 
1366
# ------------------------------------------------------------------
1367
#  PROC: gdbtk_step - step the target
1368
# ------------------------------------------------------------------
1369
proc gdbtk_step {} {
1370
  catch {gdb_immediate step}
1371
}
1372
 
1373
# ------------------------------------------------------------------
1374
#  PROC: gdbtk_next
1375
# ------------------------------------------------------------------
1376
proc gdbtk_next {} {
1377
  catch {gdb_immediate next}
1378
}
1379
 
1380
# ------------------------------------------------------------------
1381
#  PROC: gdbtk_finish
1382
# ------------------------------------------------------------------
1383
proc gdbtk_finish {} {
1384
  catch {gdb_immediate finish}
1385
}
1386
 
1387
# ------------------------------------------------------------------
1388
#  PROC: gdbtk_continue
1389
# ------------------------------------------------------------------
1390
proc gdbtk_continue {} {
1391
  catch {gdb_immediate continue}
1392
}
1393
 
1394
# ------------------------------------------------------------------
1395
#  PROC: gdbtk_stepi
1396
# ------------------------------------------------------------------
1397
proc gdbtk_stepi {} {
1398
  catch {gdb_immediate stepi}
1399
}
1400
 
1401
# ------------------------------------------------------------------
1402
#  PROC: gdbtk_nexti
1403
# ------------------------------------------------------------------
1404
proc gdbtk_nexti {} {
1405
  catch {gdb_immediate nexti}
1406
}
1407
 
1408
  # ------------------------------------------------------------------
1409
#  PROC: gdbtk_attached
1410
# ------------------------------------------------------------------
1411
#
1412
# This is called AFTER gdb has successfully done an attach.  Use it to 
1413
# bring the GUI up to a current state...
1414
proc gdbtk_attached {} {
1415
  gdbtk_update
1416
}
1417
 
1418
# ------------------------------------------------------------------
1419
#  PROC: gdbtk_detached
1420
# ------------------------------------------------------------------
1421
#
1422
# This is called AFTER gdb has successfully done an detach.  Use it to 
1423
# bring the GUI up to a current state...
1424
proc gdbtk_detached {} {
1425
  if {!$::gdb_shutting_down} {
1426
    run_hooks gdb_no_inferior_hook
1427
  }
1428
}
1429
 
1430
# ------------------------------------------------------------------
1431
#  PROC: gdbtk_stop
1432
# ------------------------------------------------------------------
1433
#
1434
# The stop button is tricky. In order to use the stop button,
1435
# the debugger must be able to keep gui alive while target_wait is
1436
# blocking (so that the user can interrupt or detach from it).
1437
# 
1438
# The best solution for this is to capture gdb deep down where it
1439
# can block. For _any_ target board, this will be in either
1440
# serial or socket code. These places call ui_loop_hook to 
1441
# keep us alive. For native unix, we use an interval timer.
1442
# Simulators either call ui_loop_hook directly (older sims, at least)
1443
# or they call gdb's os_poll_quit callback, where we insert a call
1444
# to ui_loop_hook. Some targets (like v850ice and windows native)
1445
# require a call to ui_loop_hook directly in target_wait. See comments
1446
# before gdb_stop and x_event to find out more about how this is accomplished.
1447
#
1448
# The stop button's behavior:
1449
# Pressing the stop button should attempt to stop the target. If, after
1450
# some time (like 3 seconds), gdb fails to fall out of target_wait (i.e.,
1451
# the gui's idle hooks are run), then open a dialog asking the user if
1452
# he'd like to detach.
1453
proc gdbtk_stop {} {
1454
  global _gdbtk_stop
1455
 
1456
  if {$_gdbtk_stop(timer) == ""} {
1457
    add_hook gdb_idle_hook gdbtk_stop_idle_callback
1458
    set _gdbtk_stop(timer) [after 3000 gdbtk_detach]
1459
    catch {gdb_stop}
1460
  }
1461
}
1462
 
1463
# ------------------------------------------------------------------
1464
#  PROC: gdbtk_stop_idle_callback
1465
# ------------------------------------------------------------------
1466
# This callback normally does nothing. When the stop button has
1467
# been pressed, though, and gdb has successfully stopped the target,
1468
# this callback will clean up after gdbtk_stop, removing the "Detach"
1469
# dialog (if it's open) and gettingg rid of any outstanding timers
1470
# and hooks.
1471
proc gdbtk_stop_idle_callback {} {
1472
  global _gdbtk_stop gdbtk_state
1473
 
1474
  # Check if the dialog asking if user wants to detach is open
1475
  # and unpost it if it exists.
1476
  if {$_gdbtk_stop(msg) != ""} {
1477
    set ans [list answer $_gdbtk_stop(msg)]
1478
    set gdbtk_state($ans) no
1479
  }
1480
 
1481
  if {$_gdbtk_stop(timer) != ""} {
1482
    # Cancel the timer callback
1483
    after cancel $_gdbtk_stop(timer)
1484
    set _gdbtk_stop(timer) ""
1485
    catch {remove_hook gdb_idle_hook gdbtk_stop_idle_callback}
1486
  }
1487
}
1488
 
1489
# ------------------------------------------------------------------
1490
#  PROC: gdbtk_detach
1491
# ------------------------------------------------------------------
1492
# This proc is installed as a timer event when the stop button
1493
# is pressed. If target_wait doesn't return (we were unable to stop
1494
# the target), then this proc is called.
1495
#
1496
# Open a dialog box asking if the user would like to detach. If so,
1497
# try to detach. If not, do nothing and go away.
1498
proc gdbtk_detach {} {
1499
  global _gdbtk_stop
1500
 
1501
  set _gdbtk_stop(msg) "No response from target. Detach from target\n(and stop debugging it)?"
1502
  if {[gdbtk_tcl_query  $_gdbtk_stop(msg) no]} {
1503
    catch {gdb_stop detach}
1504
  }
1505
 
1506
  set _gdbtk_stop(timer) ""
1507
  set _gdbtk_stop(msg) ""
1508
  remove_hook gdb_idle_hook gdbtk_stop_idle_callback
1509
}
1510
 
1511
# ------------------------------------------------------------------
1512
#  PROC: gdbtk_run
1513
# ------------------------------------------------------------------
1514
proc gdbtk_run {} {
1515
  run_executable
1516
}
1517
 
1518
# ------------------------------------------------------------------
1519
# PROC:  gdbtk_attach_native: attach to a running target
1520
# ------------------------------------------------------------------
1521
proc gdbtk_attach_native {} {
1522
    ManagedWin::open_dlg AttachDlg ;#-transient
1523
 
1524
    debug "ManagedWin got [AttachDlg::last_button] [AttachDlg::pid]"
1525
 
1526
    if {[AttachDlg::last_button]} {
1527
        set pid [AttachDlg::pid]
1528
        set symbol_file [AttachDlg::symbol_file]
1529
        if {![_open_file $symbol_file]} {
1530
            ManagedWin::open WarningDlg -transient \
1531
                    -message "Could not load symbols from $symbol_file."
1532
            return
1533
        }
1534
 
1535
        if {[catch {gdb_cmd "attach $pid"} result]} {
1536
            ManagedWin::open WarningDlg -transient \
1537
                    -message [list "Could not attach to $pid:\n$result"]
1538
            return
1539
        }
1540
    }
1541
}
1542
 
1543
# ------------------------------------------------------------------
1544
# PROC: set_baud -  Tell GDB the baud rate.
1545
# ------------------------------------------------------------------
1546
proc set_baud {} {
1547
  global gdb_target_name
1548
  #set target [ide_property get target-internal-name]
1549
  set baud [pref getd gdb/load/${gdb_target_name}-baud]
1550
  if {$baud == ""} {
1551
    set baud [pref get gdb/load/baud]
1552
  }
1553
#  debug "setting baud to $baud"
1554
  catch {gdb_cmd "set remotebaud $baud"}
1555
}
1556
 
1557
# ------------------------------------------------------------------
1558
# PROC: do_state_hook -
1559
# ------------------------------------------------------------------
1560
proc do_state_hook {varname ind op} {
1561
  run_hooks state_hook $varname
1562
}
1563
 
1564
# ------------------------------------------------------------------
1565
# PROC: gdbtk_disconnect -
1566
# ------------------------------------------------------------------
1567
proc gdbtk_disconnect {{async 0}} {
1568
   global gdb_loaded gdb_target_changed
1569
   catch {gdb_cmd "detach"}
1570
   # force a new target command to do something
1571
   set gdb_loaded 0
1572
   set gdb_target_changed 1
1573
   set gdb_running 0
1574
   gdbtk_idle
1575
   gdbtk_update
1576
 }
1577
 
1578
# ------------------------------------------------------------------
1579
# PROC: tstart -
1580
# ------------------------------------------------------------------
1581
proc tstart {} {
1582
   if {[catch {gdb_cmd "tstart"} errTxt]} {
1583
     tk_messageBox -title "Error" -message $errTxt -icon error \
1584
       -type ok
1585
    gdbtk_idle
1586
     return 0
1587
   }
1588
  return 1
1589
}
1590
 
1591
# ------------------------------------------------------------------
1592
# PROC: tstop -
1593
# ------------------------------------------------------------------
1594
proc tstop {} {
1595
 
1596
   if {[catch {gdb_cmd "tstop"} errTxt]} {
1597
     tk_messageBox -title "Error" -message $errTxt -icon error \
1598
       -type ok
1599
     gdbtk_idle
1600
     return 0
1601
   }
1602
   return 1
1603
 }
1604
 
1605
# ------------------------------------------------------------------
1606
# PROC: source_file -
1607
# ------------------------------------------------------------------
1608
proc source_file {} {
1609
  set file_name [tk_getOpenFile -title "Choose GDB Command file"]
1610
  if {$file_name != ""} {
1611
    gdb_cmd "source $file_name"
1612
  }
1613
}
1614
 
1615
 
1616
# -----------------------------------------------------------------------------
1617
# NAME:         gdbtk_signal
1618
#
1619
# SYNOPSIS:     gdbtk_signal {name longname}
1620
#
1621
# DESC:         This procedure is called from GDB when a signal 
1622
#               is generated, for example, a SIGSEGV.
1623
#
1624
# ARGS:         name - The name of the signal, as returned by
1625
#                       target_signal_to_name().
1626
#               longname - A description of the signal.
1627
# -----------------------------------------------------------------------------
1628
proc gdbtk_signal {name {longname ""}} {
1629
  dbug W "caught signal $name $longname"
1630
  set longname
1631
  set message "Program received signal $name, $longname"
1632
  set srcs [ManagedWin::find SrcWin]
1633
  foreach w $srcs {
1634
    $w set_status $message
1635
  }
1636
  gdbtk_tcl_ignorable_warning signal $message
1637
  update idletasks
1638
}
1639
 
1640
# Hook for clearing out executable state. Widgets should register a callback
1641
# for this hook if they have anything that may need cleaning if the user
1642
# requests to re-load an executable.
1643
define_hook gdb_clear_file_hook
1644
 
1645
# -----------------------------------------------------------------------------
1646
# NAME:       gdbtk_clear_file
1647
#
1648
# SYNOPSIS:   gdbtk_clear_file
1649
#
1650
# DESC:       This procedure is called when the user requests a new exec
1651
#             file load. It runs the gdb_clear_file_hook, which tells
1652
#             all widgets to clear state. It CANNOT call gdb_clear_file,
1653
#             since this hook runs AFTER we load a new exec file (i.e.,
1654
#             gdb_clear_file would clear the file name).
1655
#
1656
# ARGS:       none
1657
# -----------------------------------------------------------------------------
1658
proc gdbtk_clear_file {} {
1659
  global gdb_target_name
1660
 
1661
  debug
1662
  # Give widgets a chance to clean up
1663
  run_hooks gdb_clear_file_hook
1664
 
1665
  # Save the target name in case the user has already selected a
1666
  # target. No need to force the user to select it again.
1667
  set old_target $gdb_target_name
1668
 
1669
  # Finally, reset our state
1670
  initialize_gdbtk
1671
 
1672
  set gdb_target_name $old_target
1673
}
1674
 
1675
# ------------------------------------------------------------------
1676
#  PROC: intialize_gdbtk - (re)initialize gdbtk's state
1677
# ------------------------------------------------------------------
1678
proc initialize_gdbtk {} {
1679
  global gdb_exe_changed gdb_target_changed gdb_running gdb_downloading \
1680
    gdb_loaded gdb_program_has_run file_done gdb_pretty_name gdb_exec \
1681
    gdb_target_cmd download_dialog gdb_pretty_name gdb_exe_name _gdbtk_stop \
1682
    gdb_target_name gdb_target_changed gdbtk_state gdb_kod_cmd gdb_shutting_down
1683
 
1684
  # initialize state variables
1685
  set gdb_exe_changed 0
1686
  set gdb_target_changed 0
1687
  set gdb_running 0
1688
  set gdb_downloading 0
1689
  set gdb_loaded 0
1690
  set gdb_program_has_run 0
1691
  set file_done 0
1692
  set gdb_pretty_name {}
1693
  set gdb_exec {}
1694
  set gdb_target_cmd ""
1695
  set gdb_running 0
1696
  set gdb_shutting_down 0
1697
 
1698
  set download_dialog ""
1699
 
1700
  # gdb_pretty_name is the name of the GDB target as it should be
1701
  # displayed to the user.
1702
  set gdb_pretty_name ""
1703
 
1704
  # gdb_exe_name is the name of the executable we are debugging.  
1705
  set gdb_exe_name ""
1706
 
1707
  # Initialize readline
1708
  if {![info exists gdbtk_state(readline)]} {
1709
    # Only do this once...
1710
    set gdbtk_state(readline) 0
1711
    set gdbtk_state(console) ""
1712
  }
1713
 
1714
  # check for existence of a kod command and get it's name and
1715
  # text for menu entry
1716
  set gdb_kod_cmd ""
1717
  set msg ""
1718
  if {![catch {gdb_cmd "show os"} msg] && ($msg != "")} {
1719
    set line1 [string range $msg 0 [expr [string first \n $msg] -1]]
1720
    if {[regexp -- \"(.*)\" $line1 dummy cmd]} {
1721
      set gdb_kod_cmd $cmd
1722
    }
1723
  }
1724
#  debug "kod_cmd=$gdb_kod_cmd"
1725
 
1726
  # setup stop button
1727
  set _gdbtk_stop(timer) ""
1728
  set _gdbtk_stop(msg) ""
1729
 
1730
  # gdb_target_name is the name of the GDB target; that is, the argument
1731
  # to the GDB target command.
1732
  set gdb_target_name ""
1733
 
1734
  # By setting gdb_target_changed, we force a target dialog
1735
  # to be displayed on the first "run"
1736
  set gdb_target_changed 1
1737
}
1738
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.