My working unpac repository
at opam/upstream/seq 162 lines 5.3 kB view raw
1(**************************************************************************) 2(* *) 3(* OCaml *) 4(* *) 5(* Jerome Vouillon, projet Cristal, INRIA Rocquencourt *) 6(* OCaml port by John Malecki and Xavier Leroy *) 7(* *) 8(* Copyright 1996 Institut National de Recherche en Informatique et *) 9(* en Automatique. *) 10(* *) 11(* All rights reserved. This file is distributed under the terms of *) 12(* the GNU Lesser General Public License version 2.1, with the *) 13(* special exception on linking described in the file LICENSE. *) 14(* *) 15(**************************************************************************) 16 17(* Manage the loading of the program *) 18 19open Int64ops 20open Unix 21open Unix_tools 22open Debugger_config 23open Primitives 24open Parameters 25open Input_handling 26open Question 27open Program_loading 28open Time_travel 29 30(*** Connection opening and control. ***) 31 32(* Name of the file if the socket is in the unix domain.*) 33let file_name = ref (None : string option) 34 35(* Default connection handler. *) 36let buffer = Bytes.create 1024 37let control_connection pid fd = 38 if (read fd.io_fd buffer 0 1024) = 0 then 39 forget_process fd pid 40 else begin 41 prerr_string "Garbage data from process "; 42 prerr_int pid; 43 prerr_endline "" 44 end 45 46(* Accept a connection from another process. *) 47let accept_connection continue fd = 48 let (sock, _) = accept ~cloexec:true fd.io_fd in 49 let io_chan = io_channel_of_descr sock in 50 let pid = input_binary_int io_chan.io_in in 51 if pid = -1 then begin 52 let pid' = input_binary_int io_chan.io_in in 53 new_checkpoint pid' io_chan; 54 Input_handling.add_file io_chan (control_connection pid'); 55 continue () 56 end 57 else begin 58 if set_file_descriptor pid io_chan then 59 Input_handling.add_file io_chan (control_connection pid) 60 end 61 62(* Initialize the socket. *) 63let open_connection address continue = 64 try 65 let addr_info = convert_address address in 66 file_name := 67 (match addr_info with 68 | { ai_addr = ADDR_UNIX file; _} -> Some file 69 | _ -> None); 70 let sock = socket ~cloexec:true addr_info.ai_family addr_info.ai_socktype 71 addr_info.ai_protocol in 72 (try 73 bind sock addr_info.ai_addr; 74 setsockopt sock SO_REUSEADDR true; 75 listen sock 3; 76 connection := io_channel_of_descr sock; 77 Input_handling.add_file !connection (accept_connection continue); 78 connection_opened := true 79 with x -> cleanup x @@ fun () -> close sock) 80 with 81 Failure e -> prerr_endline e; raise Toplevel 82 | (Unix_error _) as err -> report_error err; raise Toplevel 83 84(* Close the socket. *) 85let close_connection () = 86 if !connection_opened then begin 87 connection_opened := false; 88 Input_handling.remove_file !connection; 89 close_io !connection; 90 match !file_name with 91 Some file -> 92 unlink file 93 | None -> 94 () 95 end 96 97(*** Kill program. ***) 98let loaded = ref false 99 100let kill_program () = 101 Breakpoints.remove_all_breakpoints (); 102 History.empty_history (); 103 kill_all_checkpoints (); 104 loaded := false; 105 close_connection () 106 107let ask_kill_program () = 108 if not !loaded then 109 true 110 else 111 let answer = yes_or_no "A program is being debugged already. Kill it" in 112 if answer then 113 kill_program (); 114 answer 115 116(*** Program loading and initializations. ***) 117 118let initialize_loading () = 119 if !debug_loading then begin 120 prerr_endline "Loading debugging information..."; 121 Printf.fprintf Stdlib.stderr "\tProgram: [%s]\n%!" !program_name; 122 end; 123 begin try access !program_name [F_OK] 124 with Unix_error _ -> 125 prerr_endline "Program not found."; 126 raise Toplevel; 127 end; 128 Symbols.clear_symbols (); 129 Symbols.read_symbols Debugcom.main_frag !program_name; 130 let Load_path.{visible; hidden} = Load_path.get_paths () in 131 let visible = visible @ !Symbols.program_source_dirs in 132 Load_path.init ~auto_include:Compmisc.auto_include ~visible ~hidden; 133 Envaux.reset_cache (); 134 if !debug_loading then 135 prerr_endline "Opening a socket..."; 136 open_connection !socket_name 137 (function () -> 138 go_to _0; 139 Symbols.set_all_events Debugcom.main_frag; 140 exit_main_loop ()) 141 142(* Ensure the program is already loaded. *) 143let ensure_loaded () = 144 if not !loaded then begin 145 print_string "Loading program... "; 146 flush Stdlib.stdout; 147 if !program_name = "" then begin 148 prerr_endline "No program specified."; 149 raise Toplevel 150 end; 151 try 152 initialize_loading(); 153 !launching_func (); 154 if !debug_loading then 155 prerr_endline "Waiting for connection..."; 156 main_loop (); 157 loaded := true; 158 prerr_endline "done." 159 with 160 x -> 161 cleanup x kill_program 162 end