1996-11-29 08:55:09 -08:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Objective Caml *)
|
|
|
|
(* *)
|
|
|
|
(* Jerome Vouillon, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* Objective Caml port by John Malecki and Xavier Leroy *)
|
|
|
|
(* *)
|
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the Q Public License version 1.0. *)
|
1996-11-29 08:55:09 -08:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(* $Id$ *)
|
|
|
|
|
|
|
|
(* Manage the loading of the program *)
|
|
|
|
|
2002-10-29 09:53:24 -08:00
|
|
|
open Int64ops
|
1996-11-29 08:55:09 -08:00
|
|
|
open Unix
|
|
|
|
open Unix_tools
|
|
|
|
open Debugger_config
|
|
|
|
open Primitives
|
|
|
|
open Parameters
|
|
|
|
open Input_handling
|
2006-12-09 05:49:10 -08:00
|
|
|
open Question
|
1996-11-29 08:55:09 -08:00
|
|
|
open Program_loading
|
|
|
|
open Time_travel
|
|
|
|
|
|
|
|
(*** Connection opening and control. ***)
|
|
|
|
|
|
|
|
(* Name of the file if the socket is in the unix domain.*)
|
|
|
|
let file_name = ref (None : string option)
|
|
|
|
|
|
|
|
(* Default connection handler. *)
|
|
|
|
let buffer = String.create 1024
|
|
|
|
let control_connection pid fd =
|
|
|
|
if (read fd.io_fd buffer 0 1024) = 0 then
|
|
|
|
forget_process fd pid
|
|
|
|
else begin
|
|
|
|
prerr_string "Garbage data from process ";
|
|
|
|
prerr_int pid;
|
|
|
|
prerr_endline ""
|
|
|
|
end
|
|
|
|
|
|
|
|
(* Accept a connection from another process. *)
|
|
|
|
let accept_connection continue fd =
|
|
|
|
let (sock, _) = accept fd.io_fd in
|
|
|
|
let io_chan = io_channel_of_descr sock in
|
|
|
|
let pid = input_binary_int io_chan.io_in in
|
1997-03-22 12:06:05 -08:00
|
|
|
if pid = -1 then begin
|
|
|
|
let pid' = input_binary_int io_chan.io_in in
|
|
|
|
new_checkpoint pid' io_chan;
|
|
|
|
Input_handling.add_file io_chan (control_connection pid');
|
1996-11-29 08:55:09 -08:00
|
|
|
continue ()
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
if set_file_descriptor pid io_chan then
|
|
|
|
Input_handling.add_file io_chan (control_connection pid)
|
|
|
|
end
|
|
|
|
|
|
|
|
(* Initialize the socket. *)
|
|
|
|
let open_connection address continue =
|
|
|
|
try
|
|
|
|
let (sock_domain, sock_address) = convert_address address in
|
|
|
|
file_name :=
|
|
|
|
(match sock_address with
|
1997-05-19 08:42:21 -07:00
|
|
|
ADDR_UNIX file ->
|
|
|
|
Some file
|
1996-11-29 08:55:09 -08:00
|
|
|
| _ ->
|
1997-05-19 08:42:21 -07:00
|
|
|
None);
|
1996-11-29 08:55:09 -08:00
|
|
|
let sock = socket sock_domain SOCK_STREAM 0 in
|
1997-05-19 08:42:21 -07:00
|
|
|
(try
|
1996-11-29 08:55:09 -08:00
|
|
|
bind sock sock_address;
|
2008-07-29 01:31:41 -07:00
|
|
|
setsockopt sock SO_REUSEADDR true;
|
1996-11-29 08:55:09 -08:00
|
|
|
listen sock 3;
|
1997-05-19 08:42:21 -07:00
|
|
|
connection := io_channel_of_descr sock;
|
1996-11-29 08:55:09 -08:00
|
|
|
Input_handling.add_file !connection (accept_connection continue);
|
1997-05-19 08:42:21 -07:00
|
|
|
connection_opened := true
|
|
|
|
with x -> close sock; raise x)
|
1996-11-29 08:55:09 -08:00
|
|
|
with
|
|
|
|
Failure _ -> raise Toplevel
|
|
|
|
| (Unix_error _) as err -> report_error err; raise Toplevel
|
|
|
|
|
|
|
|
(* Close the socket. *)
|
|
|
|
let close_connection () =
|
|
|
|
if !connection_opened then begin
|
|
|
|
connection_opened := false;
|
|
|
|
Input_handling.remove_file !connection;
|
|
|
|
close_io !connection;
|
|
|
|
match !file_name with
|
|
|
|
Some file ->
|
|
|
|
unlink file
|
|
|
|
| None ->
|
|
|
|
()
|
|
|
|
end
|
|
|
|
|
|
|
|
(*** Kill program. ***)
|
1997-03-22 12:06:05 -08:00
|
|
|
let loaded = ref false
|
|
|
|
|
1996-11-29 08:55:09 -08:00
|
|
|
let kill_program () =
|
1997-06-15 09:29:10 -07:00
|
|
|
Breakpoints.remove_all_breakpoints ();
|
1997-06-15 13:53:10 -07:00
|
|
|
History.empty_history ();
|
1997-06-15 09:29:10 -07:00
|
|
|
kill_all_checkpoints ();
|
1996-11-29 08:55:09 -08:00
|
|
|
loaded := false;
|
1997-06-15 13:53:10 -07:00
|
|
|
close_connection ()
|
1996-11-29 08:55:09 -08:00
|
|
|
|
|
|
|
let ask_kill_program () =
|
|
|
|
if not !loaded then
|
|
|
|
true
|
|
|
|
else
|
|
|
|
let answer = yes_or_no "A program is being debugged already. Kill it" in
|
|
|
|
if answer then
|
|
|
|
kill_program ();
|
|
|
|
answer
|
|
|
|
|
|
|
|
(*** Program loading and initializations. ***)
|
|
|
|
|
|
|
|
let initialize_loading () =
|
|
|
|
if !debug_loading then
|
|
|
|
prerr_endline "Loading debugging informations...";
|
2000-05-08 11:13:36 -07:00
|
|
|
begin try access !program_name [F_OK]
|
|
|
|
with Unix_error _ ->
|
|
|
|
prerr_endline "Program not found.";
|
|
|
|
raise Toplevel;
|
|
|
|
end;
|
|
|
|
Symbols.read_symbols !program_name;
|
1996-11-29 08:55:09 -08:00
|
|
|
if !debug_loading then
|
|
|
|
prerr_endline "Opening a socket...";
|
|
|
|
open_connection !socket_name
|
|
|
|
(function () ->
|
2002-10-29 09:53:24 -08:00
|
|
|
go_to _0;
|
1996-11-29 08:55:09 -08:00
|
|
|
Symbols.set_all_events();
|
|
|
|
exit_main_loop ())
|
|
|
|
|
|
|
|
(* Ensure the program is already loaded. *)
|
|
|
|
let ensure_loaded () =
|
|
|
|
if not !loaded then begin
|
1997-03-23 07:22:30 -08:00
|
|
|
print_string "Loading program... ";
|
1996-11-29 08:55:09 -08:00
|
|
|
flush Pervasives.stdout;
|
|
|
|
if !program_name = "" then begin
|
|
|
|
prerr_endline "No program specified.";
|
|
|
|
raise Toplevel
|
1997-03-23 07:22:30 -08:00
|
|
|
end;
|
1996-11-29 08:55:09 -08:00
|
|
|
try
|
|
|
|
initialize_loading();
|
|
|
|
!launching_func ();
|
|
|
|
if !debug_loading then
|
|
|
|
prerr_endline "Waiting for connection...";
|
|
|
|
main_loop ();
|
|
|
|
loaded := true;
|
1997-03-23 07:22:30 -08:00
|
|
|
prerr_endline "done."
|
1996-11-29 08:55:09 -08:00
|
|
|
with
|
|
|
|
x ->
|
1997-05-19 08:42:21 -07:00
|
|
|
kill_program();
|
|
|
|
raise x
|
1997-03-23 07:22:30 -08:00
|
|
|
end
|