OLD | NEW |
1 /* Multi-process/thread control for GDB, the GNU debugger. | 1 /* Multi-process/thread control for GDB, the GNU debugger. |
2 | 2 |
3 Copyright (C) 1986-1988, 1993-2004, 2007-2012 Free Software | 3 Copyright (C) 1986-1988, 1993-2004, 2007-2012 Free Software |
4 Foundation, Inc. | 4 Foundation, Inc. |
5 | 5 |
6 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. | 6 Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. |
7 | 7 |
8 This file is part of GDB. | 8 This file is part of GDB. |
9 | 9 |
10 This program is free software; you can redistribute it and/or modify | 10 This program is free software; you can redistribute it and/or modify |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "continuations.h" | 47 #include "continuations.h" |
48 | 48 |
49 /* Definition of struct thread_info exported to gdbthread.h. */ | 49 /* Definition of struct thread_info exported to gdbthread.h. */ |
50 | 50 |
51 /* Prototypes for exported functions. */ | 51 /* Prototypes for exported functions. */ |
52 | 52 |
53 void _initialize_thread (void); | 53 void _initialize_thread (void); |
54 | 54 |
55 /* Prototypes for local functions. */ | 55 /* Prototypes for local functions. */ |
56 | 56 |
57 static struct thread_info *thread_list = NULL; | 57 struct thread_info *thread_list = NULL; |
58 static int highest_thread_num; | 58 static int highest_thread_num; |
59 | 59 |
60 static void thread_command (char *tidstr, int from_tty); | 60 static void thread_command (char *tidstr, int from_tty); |
61 static void thread_apply_all_command (char *, int); | 61 static void thread_apply_all_command (char *, int); |
62 static int thread_alive (struct thread_info *); | 62 static int thread_alive (struct thread_info *); |
63 static void info_threads_command (char *, int); | 63 static void info_threads_command (char *, int); |
64 static void thread_apply_command (char *, int); | 64 static void thread_apply_command (char *, int); |
65 static void restore_current_thread (ptid_t); | 65 static void restore_current_thread (ptid_t); |
66 static void prune_threads (void); | 66 static void prune_threads (void); |
67 | 67 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 tp->control.step_resume_breakpoint = NULL; | 106 tp->control.step_resume_breakpoint = NULL; |
107 } | 107 } |
108 | 108 |
109 if (tp->control.exception_resume_breakpoint) | 109 if (tp->control.exception_resume_breakpoint) |
110 { | 110 { |
111 tp->control.exception_resume_breakpoint->disposition | 111 tp->control.exception_resume_breakpoint->disposition |
112 = disp_del_at_next_stop; | 112 = disp_del_at_next_stop; |
113 tp->control.exception_resume_breakpoint = NULL; | 113 tp->control.exception_resume_breakpoint = NULL; |
114 } | 114 } |
115 | 115 |
| 116 delete_longjmp_breakpoint_at_next_stop (tp->num); |
| 117 |
116 bpstat_clear (&tp->control.stop_bpstat); | 118 bpstat_clear (&tp->control.stop_bpstat); |
117 | 119 |
118 do_all_intermediate_continuations_thread (tp, 1); | 120 do_all_intermediate_continuations_thread (tp, 1); |
119 do_all_continuations_thread (tp, 1); | 121 do_all_continuations_thread (tp, 1); |
120 | |
121 delete_longjmp_breakpoint (tp->num); | |
122 } | 122 } |
123 | 123 |
124 static void | 124 static void |
125 free_thread (struct thread_info *tp) | 125 free_thread (struct thread_info *tp) |
126 { | 126 { |
127 if (tp->private) | 127 if (tp->private) |
128 { | 128 { |
129 if (tp->private_dtor) | 129 if (tp->private_dtor) |
130 tp->private_dtor (tp->private); | 130 tp->private_dtor (tp->private); |
131 else | 131 else |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 } | 1065 } |
1066 } | 1066 } |
1067 | 1067 |
1068 struct current_thread_cleanup | 1068 struct current_thread_cleanup |
1069 { | 1069 { |
1070 ptid_t inferior_ptid; | 1070 ptid_t inferior_ptid; |
1071 struct frame_id selected_frame_id; | 1071 struct frame_id selected_frame_id; |
1072 int selected_frame_level; | 1072 int selected_frame_level; |
1073 int was_stopped; | 1073 int was_stopped; |
1074 int inf_id; | 1074 int inf_id; |
| 1075 int was_removable; |
1075 }; | 1076 }; |
1076 | 1077 |
1077 static void | 1078 static void |
1078 do_restore_current_thread_cleanup (void *arg) | 1079 do_restore_current_thread_cleanup (void *arg) |
1079 { | 1080 { |
1080 struct thread_info *tp; | 1081 struct thread_info *tp; |
1081 struct current_thread_cleanup *old = arg; | 1082 struct current_thread_cleanup *old = arg; |
1082 | 1083 |
1083 tp = find_thread_ptid (old->inferior_ptid); | 1084 tp = find_thread_ptid (old->inferior_ptid); |
1084 | 1085 |
(...skipping 20 matching lines...) Expand all Loading... |
1105 && target_has_memory) | 1106 && target_has_memory) |
1106 restore_selected_frame (old->selected_frame_id, | 1107 restore_selected_frame (old->selected_frame_id, |
1107 old->selected_frame_level); | 1108 old->selected_frame_level); |
1108 } | 1109 } |
1109 | 1110 |
1110 static void | 1111 static void |
1111 restore_current_thread_cleanup_dtor (void *arg) | 1112 restore_current_thread_cleanup_dtor (void *arg) |
1112 { | 1113 { |
1113 struct current_thread_cleanup *old = arg; | 1114 struct current_thread_cleanup *old = arg; |
1114 struct thread_info *tp; | 1115 struct thread_info *tp; |
| 1116 struct inferior *inf; |
1115 | 1117 |
1116 tp = find_thread_ptid (old->inferior_ptid); | 1118 tp = find_thread_ptid (old->inferior_ptid); |
1117 if (tp) | 1119 if (tp) |
1118 tp->refcount--; | 1120 tp->refcount--; |
| 1121 inf = find_inferior_id (old->inf_id); |
| 1122 if (inf != NULL) |
| 1123 inf->removable = old->was_removable; |
1119 xfree (old); | 1124 xfree (old); |
1120 } | 1125 } |
1121 | 1126 |
1122 struct cleanup * | 1127 struct cleanup * |
1123 make_cleanup_restore_current_thread (void) | 1128 make_cleanup_restore_current_thread (void) |
1124 { | 1129 { |
1125 struct thread_info *tp; | 1130 struct thread_info *tp; |
1126 struct frame_info *frame; | 1131 struct frame_info *frame; |
1127 struct current_thread_cleanup *old; | 1132 struct current_thread_cleanup *old; |
1128 | 1133 |
1129 old = xmalloc (sizeof (struct current_thread_cleanup)); | 1134 old = xmalloc (sizeof (struct current_thread_cleanup)); |
1130 old->inferior_ptid = inferior_ptid; | 1135 old->inferior_ptid = inferior_ptid; |
1131 old->inf_id = current_inferior ()->num; | 1136 old->inf_id = current_inferior ()->num; |
| 1137 old->was_removable = current_inferior ()->removable; |
1132 | 1138 |
1133 if (!ptid_equal (inferior_ptid, null_ptid)) | 1139 if (!ptid_equal (inferior_ptid, null_ptid)) |
1134 { | 1140 { |
1135 old->was_stopped = is_stopped (inferior_ptid); | 1141 old->was_stopped = is_stopped (inferior_ptid); |
1136 if (old->was_stopped | 1142 if (old->was_stopped |
1137 && target_has_registers | 1143 && target_has_registers |
1138 && target_has_stack | 1144 && target_has_stack |
1139 && target_has_memory) | 1145 && target_has_memory) |
1140 { | 1146 { |
1141 /* When processing internal events, there might not be a | 1147 /* When processing internal events, there might not be a |
1142 selected frame. If we naively call get_selected_frame | 1148 selected frame. If we naively call get_selected_frame |
1143 here, then we can end up reading debuginfo for the | 1149 here, then we can end up reading debuginfo for the |
1144 current frame, but we don't generally need the debuginfo | 1150 current frame, but we don't generally need the debuginfo |
1145 at this point. */ | 1151 at this point. */ |
1146 frame = get_selected_frame_if_set (); | 1152 frame = get_selected_frame_if_set (); |
1147 } | 1153 } |
1148 else | 1154 else |
1149 frame = NULL; | 1155 frame = NULL; |
1150 | 1156 |
1151 old->selected_frame_id = get_frame_id (frame); | 1157 old->selected_frame_id = get_frame_id (frame); |
1152 old->selected_frame_level = frame_relative_level (frame); | 1158 old->selected_frame_level = frame_relative_level (frame); |
1153 | 1159 |
1154 tp = find_thread_ptid (inferior_ptid); | 1160 tp = find_thread_ptid (inferior_ptid); |
1155 if (tp) | 1161 if (tp) |
1156 tp->refcount++; | 1162 tp->refcount++; |
1157 } | 1163 } |
1158 | 1164 |
| 1165 current_inferior ()->removable = 0; |
| 1166 |
1159 return make_cleanup_dtor (do_restore_current_thread_cleanup, old, | 1167 return make_cleanup_dtor (do_restore_current_thread_cleanup, old, |
1160 restore_current_thread_cleanup_dtor); | 1168 restore_current_thread_cleanup_dtor); |
1161 } | 1169 } |
1162 | 1170 |
1163 /* Apply a GDB command to a list of threads. List syntax is a whitespace | 1171 /* Apply a GDB command to a list of threads. List syntax is a whitespace |
1164 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist | 1172 seperated list of numbers, or ranges, or the keyword `all'. Ranges consist |
1165 of two numbers seperated by a hyphen. Examples: | 1173 of two numbers seperated by a hyphen. Examples: |
1166 | 1174 |
1167 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4 | 1175 thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4 |
1168 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9 | 1176 thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9 |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 update_thread_list (void) | 1432 update_thread_list (void) |
1425 { | 1433 { |
1426 prune_threads (); | 1434 prune_threads (); |
1427 target_find_new_threads (); | 1435 target_find_new_threads (); |
1428 } | 1436 } |
1429 | 1437 |
1430 /* Return a new value for the selected thread's id. Return a value of 0 if | 1438 /* Return a new value for the selected thread's id. Return a value of 0 if |
1431 no thread is selected, or no threads exist. */ | 1439 no thread is selected, or no threads exist. */ |
1432 | 1440 |
1433 static struct value * | 1441 static struct value * |
1434 thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var) | 1442 thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, |
| 1443 » » void *ignore) |
1435 { | 1444 { |
1436 struct thread_info *tp = find_thread_ptid (inferior_ptid); | 1445 struct thread_info *tp = find_thread_ptid (inferior_ptid); |
1437 | 1446 |
1438 return value_from_longest (builtin_type (gdbarch)->builtin_int, | 1447 return value_from_longest (builtin_type (gdbarch)->builtin_int, |
1439 (tp ? tp->num : 0)); | 1448 (tp ? tp->num : 0)); |
1440 } | 1449 } |
1441 | 1450 |
1442 /* Commands with a prefix of `thread'. */ | 1451 /* Commands with a prefix of `thread'. */ |
1443 struct cmd_list_element *thread_cmd_list = NULL; | 1452 struct cmd_list_element *thread_cmd_list = NULL; |
1444 | 1453 |
| 1454 /* Implementation of `thread' variable. */ |
| 1455 |
| 1456 static const struct internalvar_funcs thread_funcs = |
| 1457 { |
| 1458 thread_id_make_value, |
| 1459 NULL, |
| 1460 NULL |
| 1461 }; |
| 1462 |
1445 void | 1463 void |
1446 _initialize_thread (void) | 1464 _initialize_thread (void) |
1447 { | 1465 { |
1448 static struct cmd_list_element *thread_apply_list = NULL; | 1466 static struct cmd_list_element *thread_apply_list = NULL; |
1449 | 1467 |
1450 add_info ("threads", info_threads_command, | 1468 add_info ("threads", info_threads_command, |
1451 _("Display currently known threads.\n\ | 1469 _("Display currently known threads.\n\ |
1452 Usage: info threads [ID]...\n\ | 1470 Usage: info threads [ID]...\n\ |
1453 Optional arguments are thread IDs with spaces between.\n\ | 1471 Optional arguments are thread IDs with spaces between.\n\ |
1454 If no arguments, all threads are displayed.")); | 1472 If no arguments, all threads are displayed.")); |
(...skipping 25 matching lines...) Expand all Loading... |
1480 add_com_alias ("t", "thread", class_run, 1); | 1498 add_com_alias ("t", "thread", class_run, 1); |
1481 | 1499 |
1482 add_setshow_boolean_cmd ("thread-events", no_class, | 1500 add_setshow_boolean_cmd ("thread-events", no_class, |
1483 &print_thread_events, _("\ | 1501 &print_thread_events, _("\ |
1484 Set printing of thread events (such as thread start and exit)."), _("\ | 1502 Set printing of thread events (such as thread start and exit)."), _("\ |
1485 Show printing of thread events (such as thread start and exit)."), NULL, | 1503 Show printing of thread events (such as thread start and exit)."), NULL, |
1486 NULL, | 1504 NULL, |
1487 show_print_thread_events, | 1505 show_print_thread_events, |
1488 &setprintlist, &showprintlist); | 1506 &setprintlist, &showprintlist); |
1489 | 1507 |
1490 create_internalvar_type_lazy ("_thread", thread_id_make_value); | 1508 create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); |
1491 } | 1509 } |
OLD | NEW |