diff options
| author | Dmitry Antipov | 2014-05-30 11:40:29 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2014-05-30 11:40:29 +0400 |
| commit | 8d3103b1efd32a2faf257e26a5474e12543ce798 (patch) | |
| tree | 110af642ef3cecf9bc207d56add307156d004cb2 /src | |
| parent | 8cf1e6e67926683e38809adced986d255124afd5 (diff) | |
| download | emacs-8d3103b1efd32a2faf257e26a5474e12543ce798.tar.gz emacs-8d3103b1efd32a2faf257e26a5474e12543ce798.zip | |
Debugging facility to check whether 'const char *' points to
relocatable data of non-pure Lisp string.
* alloc.c (maybe_lisp_pointer): New function, refactored out of ...
(mark_maybe_pointer): ... adjusted user.
(relocatable_string_data_p): New function.
* lisp.h (relocatable_string_data_p): Add prototype.
* xdisp.c (message_with_string): If ENABLE_CHECKING, make sure
the pointer to relocatable Lisp data is not used.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/alloc.c | 41 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 10 |
4 files changed, 52 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6ecf7dbee99..a4f1cb7590a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2014-05-30 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Debugging facility to check whether 'const char *' points to | ||
| 4 | relocatable data of non-pure Lisp string. | ||
| 5 | * alloc.c (maybe_lisp_pointer): New function, refactored out of ... | ||
| 6 | (mark_maybe_pointer): ... adjusted user. | ||
| 7 | (relocatable_string_data_p): New function. | ||
| 8 | * lisp.h (relocatable_string_data_p): Add prototype. | ||
| 9 | * xdisp.c (message_with_string): If ENABLE_CHECKING, make sure | ||
| 10 | the pointer to relocatable Lisp data is not used. | ||
| 11 | |||
| 1 | 2014-05-30 Paul Eggert <eggert@cs.ucla.edu> | 12 | 2014-05-30 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 13 | ||
| 3 | Don't let SIGINT handling block SIGCHLD indefinitely (Bug#17561). | 14 | Don't let SIGINT handling block SIGCHLD indefinitely (Bug#17561). |
diff --git a/src/alloc.c b/src/alloc.c index ab383f34f04..d728c356109 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4547,7 +4547,16 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4547 | } | 4547 | } |
| 4548 | } | 4548 | } |
| 4549 | 4549 | ||
| 4550 | /* Return true if P can point to Lisp data, and false otherwise. | ||
| 4551 | USE_LSB_TAG needs Lisp data to be aligned on multiples of GCALIGNMENT. | ||
| 4552 | Otherwise, assume that Lisp data is aligned on even addresses. */ | ||
| 4550 | 4553 | ||
| 4554 | static bool | ||
| 4555 | maybe_lisp_pointer (void *p) | ||
| 4556 | { | ||
| 4557 | return !((intptr_t) p % (USE_LSB_TAG ? GCALIGNMENT : 2)); | ||
| 4558 | } | ||
| 4559 | |||
| 4551 | /* If P points to Lisp data, mark that as live if it isn't already | 4560 | /* If P points to Lisp data, mark that as live if it isn't already |
| 4552 | marked. */ | 4561 | marked. */ |
| 4553 | 4562 | ||
| @@ -4561,10 +4570,7 @@ mark_maybe_pointer (void *p) | |||
| 4561 | VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); | 4570 | VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); |
| 4562 | #endif | 4571 | #endif |
| 4563 | 4572 | ||
| 4564 | /* Quickly rule out some values which can't point to Lisp data. | 4573 | if (!maybe_lisp_pointer (p)) |
| 4565 | USE_LSB_TAG needs Lisp data to be aligned on multiples of GCALIGNMENT. | ||
| 4566 | Otherwise, assume that Lisp data is aligned on even addresses. */ | ||
| 4567 | if ((intptr_t) p % (USE_LSB_TAG ? GCALIGNMENT : 2)) | ||
| 4568 | return; | 4574 | return; |
| 4569 | 4575 | ||
| 4570 | m = mem_find (p); | 4576 | m = mem_find (p); |
| @@ -5007,9 +5013,34 @@ valid_lisp_object_p (Lisp_Object obj) | |||
| 5007 | #endif | 5013 | #endif |
| 5008 | } | 5014 | } |
| 5009 | 5015 | ||
| 5016 | /* If GC_MARK_STACK, return 1 if STR is a relocatable data of Lisp_String | ||
| 5017 | (i.e. there is a non-pure Lisp_Object X so that SDATA (X) == STR) and 0 | ||
| 5018 | if not. Otherwise we can't rely on valid_lisp_object_p and return -1. | ||
| 5019 | This function is slow and should be used for debugging purposes. */ | ||
| 5010 | 5020 | ||
| 5021 | int | ||
| 5022 | relocatable_string_data_p (const char *str) | ||
| 5023 | { | ||
| 5024 | if (PURE_POINTER_P (str)) | ||
| 5025 | return 0; | ||
| 5026 | #if GC_MARK_STACK | ||
| 5027 | if (str) | ||
| 5028 | { | ||
| 5029 | struct sdata *sdata | ||
| 5030 | = (struct sdata *) (str - offsetof (struct sdata, data)); | ||
| 5031 | |||
| 5032 | if (valid_pointer_p (sdata) | ||
| 5033 | && valid_pointer_p (sdata->string) | ||
| 5034 | && maybe_lisp_pointer (sdata->string)) | ||
| 5035 | return (valid_lisp_object_p | ||
| 5036 | (make_lisp_ptr (sdata->string, Lisp_String)) | ||
| 5037 | && (const char *) sdata->string->data == str); | ||
| 5038 | } | ||
| 5039 | return 0; | ||
| 5040 | #endif /* GC_MARK_STACK */ | ||
| 5041 | return -1; | ||
| 5042 | } | ||
| 5011 | 5043 | ||
| 5012 | |||
| 5013 | /*********************************************************************** | 5044 | /*********************************************************************** |
| 5014 | Pure Storage Management | 5045 | Pure Storage Management |
| 5015 | ***********************************************************************/ | 5046 | ***********************************************************************/ |
diff --git a/src/lisp.h b/src/lisp.h index bbe2e4e9ce2..5002fa2a282 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3747,6 +3747,7 @@ extern void init_alloc (void); | |||
| 3747 | extern void syms_of_alloc (void); | 3747 | extern void syms_of_alloc (void); |
| 3748 | extern struct buffer * allocate_buffer (void); | 3748 | extern struct buffer * allocate_buffer (void); |
| 3749 | extern int valid_lisp_object_p (Lisp_Object); | 3749 | extern int valid_lisp_object_p (Lisp_Object); |
| 3750 | extern int relocatable_string_data_p (const char *); | ||
| 3750 | #ifdef GC_CHECK_CONS_LIST | 3751 | #ifdef GC_CHECK_CONS_LIST |
| 3751 | extern void check_cons_list (void); | 3752 | extern void check_cons_list (void); |
| 3752 | #else | 3753 | #else |
diff --git a/src/xdisp.c b/src/xdisp.c index 1585164f439..fbe87ed847a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -10201,19 +10201,17 @@ message_with_string (const char *m, Lisp_Object string, int log) | |||
| 10201 | { | 10201 | { |
| 10202 | if (m) | 10202 | if (m) |
| 10203 | { | 10203 | { |
| 10204 | /* ENCODE_SYSTEM below can GC and/or relocate the Lisp | 10204 | /* ENCODE_SYSTEM below can GC and/or relocate the |
| 10205 | String whose data pointer might be passed to us in M. So | 10205 | Lisp data, so make sure we don't use it here. */ |
| 10206 | we use a local copy. */ | 10206 | eassert (relocatable_string_data_p (m) != 1); |
| 10207 | char *fmt = xstrdup (m); | ||
| 10208 | 10207 | ||
| 10209 | if (noninteractive_need_newline) | 10208 | if (noninteractive_need_newline) |
| 10210 | putc ('\n', stderr); | 10209 | putc ('\n', stderr); |
| 10211 | noninteractive_need_newline = 0; | 10210 | noninteractive_need_newline = 0; |
| 10212 | fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string))); | 10211 | fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string))); |
| 10213 | if (!cursor_in_echo_area) | 10212 | if (!cursor_in_echo_area) |
| 10214 | fprintf (stderr, "\n"); | 10213 | fprintf (stderr, "\n"); |
| 10215 | fflush (stderr); | 10214 | fflush (stderr); |
| 10216 | xfree (fmt); | ||
| 10217 | } | 10215 | } |
| 10218 | } | 10216 | } |
| 10219 | else if (INTERACTIVE) | 10217 | else if (INTERACTIVE) |