• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisión9c6595ab6873e15fe533b05bb7b98c11f17c5d57 (tree)
Tiempo2015-10-29 21:55:01
AutorPedro Alves <palves@redh...>
CommiterPedro Alves

Log Message

Don't assume break/continue inside a TRY block works

In C++, this:

try
{
break;
}
catch (..)
{}

is invalid. However, because our TRY/CATCH macros support it in C,
the C++ version of those macros support it too. To catch such
assumptions, this adds a (disabled) hack that maps TRY/CATCH to raw
C++ try/catch. Then it goes through all instances that building on
x86_64 GNU/Linux trips on, fixing them.

This isn't strictly necessary yet, but I think it's nicer to try to
keep the tree in a state where it's easier to eliminate the TRY/CATCH
macros.

gdb/ChangeLog:
2015-10-29 Pedro Alves <palves@redhat.com>

* dwarf2-frame-tailcall.c (dwarf2_tailcall_sniffer_first): Don't
assume that "break" breaks out of a TRY/CATCH.
* python/py-framefilter.c (py_print_single_arg): Don't assume
"continue" breaks out of a TRY/CATCH.
* python/py-value.c (valpy_binop_throw): New function, factored
out from ...
(valpy_binop): ... this.
(valpy_richcompare_throw): New function, factored
out from ...
(valpy_richcompare): ... this.
* solib.c (solib_read_symbols): Don't assume "break" breaks out
of a TRY/CATCH.
* common/common-exceptions.h [USE_RAW_CXX_TRY]
<TRY/CATCH/END_CATCH>: Define as 1-1 wrappers around try/catch.

Cambiar Resumen

Diferencia incremental

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
1+2015-10-29 Pedro Alves <palves@redhat.com>
2+
3+ * dwarf2-frame-tailcall.c (dwarf2_tailcall_sniffer_first): Don't
4+ assume that "break" breaks out of a TRY/CATCH.
5+ * python/py-framefilter.c (py_print_single_arg): Don't assume
6+ "continue" breaks out of a TRY/CATCH.
7+ * python/py-value.c (valpy_binop_throw): New function, factored
8+ out from ...
9+ (valpy_binop): ... this.
10+ (valpy_richcompare_throw): New function, factored
11+ out from ...
12+ (valpy_richcompare): ... this.
13+ * solib.c (solib_read_symbols): Don't assume "break" breaks out
14+ of a TRY/CATCH.
15+ * common/common-exceptions.h [USE_RAW_CXX_TRY]
16+ <TRY/CATCH/END_CATCH>: Define as 1-1 wrappers around try/catch.
17+
118 2015-10-28 Simon Dardis <Simon.Dardis@imgtec.com>
219
320 * mips-linux-tdep.c (mips_linux_in_dynsym_stub): Recognise 'or'
--- a/gdb/common/common-exceptions.h
+++ b/gdb/common/common-exceptions.h
@@ -195,6 +195,14 @@ struct exception_try_scope
195195 void *saved_state;
196196 };
197197
198+/* Define this to build with TRY/CATCH mapped directly to raw
199+ try/catch. GDB won't work correctly, but building that way catches
200+ code tryin to break/continue out of the try block, along with
201+ spurious code between the TRY and the CATCH block. */
202+//#define USE_RAW_CXX_TRY
203+
204+#ifndef USE_RAW_CXX_TRY
205+
198206 /* We still need to wrap TRY/CATCH in C++ so that cleanups and C++
199207 exceptions can coexist. The TRY blocked is wrapped in a
200208 do/while(0) so that break/continue within the block works the same
@@ -216,6 +224,14 @@ struct exception_try_scope
216224 { \
217225 exception_rethrow (); \
218226 }
227+#else
228+
229+#define TRY try
230+#define CATCH(EXCEPTION, MASK) \
231+ catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
232+#define END_CATCH
233+
234+#endif
219235
220236 /* The exception types client code may catch. They're just shims
221237 around gdb_exception that add nothing but type info. Which is used
--- a/gdb/dwarf2-frame-tailcall.c
+++ b/gdb/dwarf2-frame-tailcall.c
@@ -386,13 +386,15 @@ dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
386386 /* call_site_find_chain can throw an exception. */
387387 chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc);
388388
389- if (entry_cfa_sp_offsetp == NULL)
390- break;
391- sp_regnum = gdbarch_sp_regnum (prev_gdbarch);
392- if (sp_regnum == -1)
393- break;
394- prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum);
395- prev_sp_p = 1;
389+ if (entry_cfa_sp_offsetp != NULL)
390+ {
391+ sp_regnum = gdbarch_sp_regnum (prev_gdbarch);
392+ if (sp_regnum != -1)
393+ {
394+ prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum);
395+ prev_sp_p = 1;
396+ }
397+ }
396398 }
397399 CATCH (except, RETURN_MASK_ERROR)
398400 {
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -448,37 +448,39 @@ py_print_single_arg (struct ui_out *out,
448448 {
449449 retval = EXT_LANG_BT_ERROR;
450450 do_cleanups (cleanups);
451- continue;
452451 }
453452 }
454453
455- if (val != NULL)
456- annotate_arg_value (value_type (val));
457-
458- /* If the output is to the CLI, and the user option "set print
459- frame-arguments" is set to none, just output "...". */
460- if (! ui_out_is_mi_like_p (out) && args_type == NO_VALUES)
461- ui_out_field_string (out, "value", "...");
462- else
454+ if (retval != EXT_LANG_BT_ERROR)
463455 {
464- /* Otherwise, print the value for both MI and the CLI, except
465- for the case of MI_PRINT_NO_VALUES. */
466- if (args_type != NO_VALUES)
456+ if (val != NULL)
457+ annotate_arg_value (value_type (val));
458+
459+ /* If the output is to the CLI, and the user option "set print
460+ frame-arguments" is set to none, just output "...". */
461+ if (! ui_out_is_mi_like_p (out) && args_type == NO_VALUES)
462+ ui_out_field_string (out, "value", "...");
463+ else
467464 {
468- if (val == NULL)
465+ /* Otherwise, print the value for both MI and the CLI, except
466+ for the case of MI_PRINT_NO_VALUES. */
467+ if (args_type != NO_VALUES)
469468 {
470- gdb_assert (fa != NULL && fa->error != NULL);
471- ui_out_field_fmt (out, "value",
472- _("<error reading variable: %s>"),
473- fa->error);
469+ if (val == NULL)
470+ {
471+ gdb_assert (fa != NULL && fa->error != NULL);
472+ ui_out_field_fmt (out, "value",
473+ _("<error reading variable: %s>"),
474+ fa->error);
475+ }
476+ else if (py_print_value (out, val, opts, 0, args_type, language)
477+ == EXT_LANG_BT_ERROR)
478+ retval = EXT_LANG_BT_ERROR;
474479 }
475- else if (py_print_value (out, val, opts, 0, args_type, language)
476- == EXT_LANG_BT_ERROR)
477- retval = EXT_LANG_BT_ERROR;
478480 }
479- }
480481
481- do_cleanups (cleanups);
482+ do_cleanups (cleanups);
483+ }
482484 }
483485 CATCH (except, RETURN_MASK_ERROR)
484486 {
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1018,133 +1018,147 @@ enum valpy_opcode
10181018 #define STRIP_REFERENCE(TYPE) \
10191019 ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
10201020
1021-/* Returns a value object which is the result of applying the operation
1022- specified by OPCODE to the given arguments. Returns NULL on error, with
1023- a python exception set. */
1021+/* Helper for valpy_binop. Returns a value object which is the result
1022+ of applying the operation specified by OPCODE to the given
1023+ arguments. Throws a GDB exception on error. */
1024+
10241025 static PyObject *
1025-valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
1026+valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
10261027 {
10271028 PyObject *result = NULL;
10281029
1029- TRY
1030+ struct value *arg1, *arg2;
1031+ struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
1032+ struct value *res_val = NULL;
1033+ enum exp_opcode op = OP_NULL;
1034+ int handled = 0;
1035+
1036+ /* If the gdb.Value object is the second operand, then it will be
1037+ passed to us as the OTHER argument, and SELF will be an entirely
1038+ different kind of object, altogether. Because of this, we can't
1039+ assume self is a gdb.Value object and need to convert it from
1040+ python as well. */
1041+ arg1 = convert_value_from_python (self);
1042+ if (arg1 == NULL)
10301043 {
1031- struct value *arg1, *arg2;
1032- struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
1033- struct value *res_val = NULL;
1034- enum exp_opcode op = OP_NULL;
1035- int handled = 0;
1036-
1037- /* If the gdb.Value object is the second operand, then it will be passed
1038- to us as the OTHER argument, and SELF will be an entirely different
1039- kind of object, altogether. Because of this, we can't assume self is
1040- a gdb.Value object and need to convert it from python as well. */
1041- arg1 = convert_value_from_python (self);
1042- if (arg1 == NULL)
1043- {
1044- do_cleanups (cleanup);
1045- break;
1046- }
1044+ do_cleanups (cleanup);
1045+ return NULL;
1046+ }
10471047
1048- arg2 = convert_value_from_python (other);
1049- if (arg2 == NULL)
1050- {
1051- do_cleanups (cleanup);
1052- break;
1053- }
1048+ arg2 = convert_value_from_python (other);
1049+ if (arg2 == NULL)
1050+ {
1051+ do_cleanups (cleanup);
1052+ return NULL;
1053+ }
10541054
1055- switch (opcode)
1056- {
1057- case VALPY_ADD:
1055+ switch (opcode)
1056+ {
1057+ case VALPY_ADD:
1058+ {
1059+ struct type *ltype = value_type (arg1);
1060+ struct type *rtype = value_type (arg2);
1061+
1062+ ltype = check_typedef (ltype);
1063+ ltype = STRIP_REFERENCE (ltype);
1064+ rtype = check_typedef (rtype);
1065+ rtype = STRIP_REFERENCE (rtype);
1066+
1067+ handled = 1;
1068+ if (TYPE_CODE (ltype) == TYPE_CODE_PTR
1069+ && is_integral_type (rtype))
1070+ res_val = value_ptradd (arg1, value_as_long (arg2));
1071+ else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
1072+ && is_integral_type (ltype))
1073+ res_val = value_ptradd (arg2, value_as_long (arg1));
1074+ else
10581075 {
1059- struct type *ltype = value_type (arg1);
1060- struct type *rtype = value_type (arg2);
1061-
1062- ltype = check_typedef (ltype);
1063- ltype = STRIP_REFERENCE (ltype);
1064- rtype = check_typedef (rtype);
1065- rtype = STRIP_REFERENCE (rtype);
1066-
1067- handled = 1;
1068- if (TYPE_CODE (ltype) == TYPE_CODE_PTR
1069- && is_integral_type (rtype))
1070- res_val = value_ptradd (arg1, value_as_long (arg2));
1071- else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
1072- && is_integral_type (ltype))
1073- res_val = value_ptradd (arg2, value_as_long (arg1));
1074- else
1075- {
1076- handled = 0;
1077- op = BINOP_ADD;
1078- }
1076+ handled = 0;
1077+ op = BINOP_ADD;
10791078 }
1080- break;
1081- case VALPY_SUB:
1079+ }
1080+ break;
1081+ case VALPY_SUB:
1082+ {
1083+ struct type *ltype = value_type (arg1);
1084+ struct type *rtype = value_type (arg2);
1085+
1086+ ltype = check_typedef (ltype);
1087+ ltype = STRIP_REFERENCE (ltype);
1088+ rtype = check_typedef (rtype);
1089+ rtype = STRIP_REFERENCE (rtype);
1090+
1091+ handled = 1;
1092+ if (TYPE_CODE (ltype) == TYPE_CODE_PTR
1093+ && TYPE_CODE (rtype) == TYPE_CODE_PTR)
1094+ /* A ptrdiff_t for the target would be preferable here. */
1095+ res_val = value_from_longest (builtin_type_pyint,
1096+ value_ptrdiff (arg1, arg2));
1097+ else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
1098+ && is_integral_type (rtype))
1099+ res_val = value_ptradd (arg1, - value_as_long (arg2));
1100+ else
10821101 {
1083- struct type *ltype = value_type (arg1);
1084- struct type *rtype = value_type (arg2);
1085-
1086- ltype = check_typedef (ltype);
1087- ltype = STRIP_REFERENCE (ltype);
1088- rtype = check_typedef (rtype);
1089- rtype = STRIP_REFERENCE (rtype);
1090-
1091- handled = 1;
1092- if (TYPE_CODE (ltype) == TYPE_CODE_PTR
1093- && TYPE_CODE (rtype) == TYPE_CODE_PTR)
1094- /* A ptrdiff_t for the target would be preferable here. */
1095- res_val = value_from_longest (builtin_type_pyint,
1096- value_ptrdiff (arg1, arg2));
1097- else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
1098- && is_integral_type (rtype))
1099- res_val = value_ptradd (arg1, - value_as_long (arg2));
1100- else
1101- {
1102- handled = 0;
1103- op = BINOP_SUB;
1104- }
1102+ handled = 0;
1103+ op = BINOP_SUB;
11051104 }
1106- break;
1107- case VALPY_MUL:
1108- op = BINOP_MUL;
1109- break;
1110- case VALPY_DIV:
1111- op = BINOP_DIV;
1112- break;
1113- case VALPY_REM:
1114- op = BINOP_REM;
1115- break;
1116- case VALPY_POW:
1117- op = BINOP_EXP;
1118- break;
1119- case VALPY_LSH:
1120- op = BINOP_LSH;
1121- break;
1122- case VALPY_RSH:
1123- op = BINOP_RSH;
1124- break;
1125- case VALPY_BITAND:
1126- op = BINOP_BITWISE_AND;
1127- break;
1128- case VALPY_BITOR:
1129- op = BINOP_BITWISE_IOR;
1130- break;
1131- case VALPY_BITXOR:
1132- op = BINOP_BITWISE_XOR;
1133- break;
1134- }
1105+ }
1106+ break;
1107+ case VALPY_MUL:
1108+ op = BINOP_MUL;
1109+ break;
1110+ case VALPY_DIV:
1111+ op = BINOP_DIV;
1112+ break;
1113+ case VALPY_REM:
1114+ op = BINOP_REM;
1115+ break;
1116+ case VALPY_POW:
1117+ op = BINOP_EXP;
1118+ break;
1119+ case VALPY_LSH:
1120+ op = BINOP_LSH;
1121+ break;
1122+ case VALPY_RSH:
1123+ op = BINOP_RSH;
1124+ break;
1125+ case VALPY_BITAND:
1126+ op = BINOP_BITWISE_AND;
1127+ break;
1128+ case VALPY_BITOR:
1129+ op = BINOP_BITWISE_IOR;
1130+ break;
1131+ case VALPY_BITXOR:
1132+ op = BINOP_BITWISE_XOR;
1133+ break;
1134+ }
1135+
1136+ if (!handled)
1137+ {
1138+ if (binop_user_defined_p (op, arg1, arg2))
1139+ res_val = value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
1140+ else
1141+ res_val = value_binop (arg1, arg2, op);
1142+ }
11351143
1136- if (!handled)
1137- {
1138- if (binop_user_defined_p (op, arg1, arg2))
1139- res_val = value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
1140- else
1141- res_val = value_binop (arg1, arg2, op);
1142- }
1144+ if (res_val)
1145+ result = value_to_value_object (res_val);
11431146
1144- if (res_val)
1145- result = value_to_value_object (res_val);
1147+ do_cleanups (cleanup);
1148+ return result;
1149+}
11461150
1147- do_cleanups (cleanup);
1151+/* Returns a value object which is the result of applying the operation
1152+ specified by OPCODE to the given arguments. Returns NULL on error, with
1153+ a python exception set. */
1154+static PyObject *
1155+valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
1156+{
1157+ PyObject *result = NULL;
1158+
1159+ TRY
1160+ {
1161+ result = valpy_binop_throw (opcode, self, other);
11481162 }
11491163 CATCH (except, RETURN_MASK_ALL)
11501164 {
@@ -1351,6 +1365,63 @@ valpy_xor (PyObject *self, PyObject *other)
13511365 return valpy_binop (VALPY_BITXOR, self, other);
13521366 }
13531367
1368+/* Helper for valpy_richcompare. Implements comparison operations for
1369+ value objects. Returns true/false on success. Returns -1 with a
1370+ Python exception set if a Python error is detected. Throws a GDB
1371+ exception on other errors (memory error, etc.). */
1372+
1373+static int
1374+valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
1375+{
1376+ int result;
1377+ struct value *value_other;
1378+ struct value *value_self;
1379+ struct value *mark = value_mark ();
1380+ struct cleanup *cleanup;
1381+
1382+ value_other = convert_value_from_python (other);
1383+ if (value_other == NULL)
1384+ return -1;
1385+
1386+ cleanup = make_cleanup_value_free_to_mark (mark);
1387+
1388+ value_self = ((value_object *) self)->value;
1389+
1390+ switch (op)
1391+ {
1392+ case Py_LT:
1393+ result = value_less (value_self, value_other);
1394+ break;
1395+ case Py_LE:
1396+ result = value_less (value_self, value_other)
1397+ || value_equal (value_self, value_other);
1398+ break;
1399+ case Py_EQ:
1400+ result = value_equal (value_self, value_other);
1401+ break;
1402+ case Py_NE:
1403+ result = !value_equal (value_self, value_other);
1404+ break;
1405+ case Py_GT:
1406+ result = value_less (value_other, value_self);
1407+ break;
1408+ case Py_GE:
1409+ result = (value_less (value_other, value_self)
1410+ || value_equal (value_self, value_other));
1411+ break;
1412+ default:
1413+ /* Can't happen. */
1414+ PyErr_SetString (PyExc_NotImplementedError,
1415+ _("Invalid operation on gdb.Value."));
1416+ result = -1;
1417+ break;
1418+ }
1419+
1420+ do_cleanups (cleanup);
1421+ return result;
1422+}
1423+
1424+
13541425 /* Implements comparison operations for value objects. Returns NULL on error,
13551426 with a python exception set. */
13561427 static PyObject *
@@ -1379,48 +1450,7 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
13791450
13801451 TRY
13811452 {
1382- struct value *value_other, *mark = value_mark ();
1383- struct cleanup *cleanup;
1384-
1385- value_other = convert_value_from_python (other);
1386- if (value_other == NULL)
1387- {
1388- result = -1;
1389- break;
1390- }
1391-
1392- cleanup = make_cleanup_value_free_to_mark (mark);
1393-
1394- switch (op) {
1395- case Py_LT:
1396- result = value_less (((value_object *) self)->value, value_other);
1397- break;
1398- case Py_LE:
1399- result = value_less (((value_object *) self)->value, value_other)
1400- || value_equal (((value_object *) self)->value, value_other);
1401- break;
1402- case Py_EQ:
1403- result = value_equal (((value_object *) self)->value, value_other);
1404- break;
1405- case Py_NE:
1406- result = !value_equal (((value_object *) self)->value, value_other);
1407- break;
1408- case Py_GT:
1409- result = value_less (value_other, ((value_object *) self)->value);
1410- break;
1411- case Py_GE:
1412- result = value_less (value_other, ((value_object *) self)->value)
1413- || value_equal (((value_object *) self)->value, value_other);
1414- break;
1415- default:
1416- /* Can't happen. */
1417- PyErr_SetString (PyExc_NotImplementedError,
1418- _("Invalid operation on gdb.Value."));
1419- result = -1;
1420- break;
1421- }
1422-
1423- do_cleanups (cleanup);
1453+ result = valpy_richcompare_throw (self, other, op);
14241454 }
14251455 CATCH (except, RETURN_MASK_ALL)
14261456 {
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -696,16 +696,16 @@ solib_read_symbols (struct so_list *so, int flags)
696696 && so->objfile->addr_low == so->addr_low)
697697 break;
698698 }
699- if (so->objfile != NULL)
700- break;
701-
702- sap = build_section_addr_info_from_section_table (so->sections,
703- so->sections_end);
704- so->objfile = symbol_file_add_from_bfd (so->abfd, so->so_name,
705- flags, sap, OBJF_SHARED,
706- NULL);
707- so->objfile->addr_low = so->addr_low;
708- free_section_addr_info (sap);
699+ if (so->objfile == NULL)
700+ {
701+ sap = build_section_addr_info_from_section_table (so->sections,
702+ so->sections_end);
703+ so->objfile = symbol_file_add_from_bfd (so->abfd, so->so_name,
704+ flags, sap, OBJF_SHARED,
705+ NULL);
706+ so->objfile->addr_low = so->addr_low;
707+ free_section_addr_info (sap);
708+ }
709709
710710 so->symbols_loaded = 1;
711711 }