Commit 8d3103b1 authored by Dmitry Antipov's avatar Dmitry Antipov
Browse files

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.
parent 8cf1e6e6
2014-05-30 Dmitry Antipov <dmantipov@yandex.ru>
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.
2014-05-30 Paul Eggert <eggert@cs.ucla.edu> 2014-05-30 Paul Eggert <eggert@cs.ucla.edu>
Don't let SIGINT handling block SIGCHLD indefinitely (Bug#17561). Don't let SIGINT handling block SIGCHLD indefinitely (Bug#17561).
......
...@@ -4547,7 +4547,16 @@ mark_maybe_object (Lisp_Object obj) ...@@ -4547,7 +4547,16 @@ mark_maybe_object (Lisp_Object obj)
} }
} }
/* Return true if P can point to Lisp data, and false otherwise.
USE_LSB_TAG needs Lisp data to be aligned on multiples of GCALIGNMENT.
Otherwise, assume that Lisp data is aligned on even addresses. */
static bool
maybe_lisp_pointer (void *p)
{
return !((intptr_t) p % (USE_LSB_TAG ? GCALIGNMENT : 2));
}
/* If P points to Lisp data, mark that as live if it isn't already /* If P points to Lisp data, mark that as live if it isn't already
marked. */ marked. */
...@@ -4561,10 +4570,7 @@ mark_maybe_pointer (void *p) ...@@ -4561,10 +4570,7 @@ mark_maybe_pointer (void *p)
VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p));
#endif #endif
/* Quickly rule out some values which can't point to Lisp data. if (!maybe_lisp_pointer (p))
USE_LSB_TAG needs Lisp data to be aligned on multiples of GCALIGNMENT.
Otherwise, assume that Lisp data is aligned on even addresses. */
if ((intptr_t) p % (USE_LSB_TAG ? GCALIGNMENT : 2))
return; return;
m = mem_find (p); m = mem_find (p);
...@@ -5007,9 +5013,34 @@ valid_lisp_object_p (Lisp_Object obj) ...@@ -5007,9 +5013,34 @@ valid_lisp_object_p (Lisp_Object obj)
#endif #endif
} }
/* If GC_MARK_STACK, return 1 if STR is a relocatable data of Lisp_String
(i.e. there is a non-pure Lisp_Object X so that SDATA (X) == STR) and 0
if not. Otherwise we can't rely on valid_lisp_object_p and return -1.
This function is slow and should be used for debugging purposes. */
int
relocatable_string_data_p (const char *str)
{
if (PURE_POINTER_P (str))
return 0;
#if GC_MARK_STACK
if (str)
{
struct sdata *sdata
= (struct sdata *) (str - offsetof (struct sdata, data));
if (valid_pointer_p (sdata)
&& valid_pointer_p (sdata->string)
&& maybe_lisp_pointer (sdata->string))
return (valid_lisp_object_p
(make_lisp_ptr (sdata->string, Lisp_String))
&& (const char *) sdata->string->data == str);
}
return 0;
#endif /* GC_MARK_STACK */
return -1;
}
/*********************************************************************** /***********************************************************************
Pure Storage Management Pure Storage Management
***********************************************************************/ ***********************************************************************/
......
...@@ -3747,6 +3747,7 @@ extern void init_alloc (void); ...@@ -3747,6 +3747,7 @@ extern void init_alloc (void);
extern void syms_of_alloc (void); extern void syms_of_alloc (void);
extern struct buffer * allocate_buffer (void); extern struct buffer * allocate_buffer (void);
extern int valid_lisp_object_p (Lisp_Object); extern int valid_lisp_object_p (Lisp_Object);
extern int relocatable_string_data_p (const char *);
#ifdef GC_CHECK_CONS_LIST #ifdef GC_CHECK_CONS_LIST
extern void check_cons_list (void); extern void check_cons_list (void);
#else #else
......
...@@ -10201,19 +10201,17 @@ message_with_string (const char *m, Lisp_Object string, int log) ...@@ -10201,19 +10201,17 @@ message_with_string (const char *m, Lisp_Object string, int log)
{ {
if (m) if (m)
{ {
/* ENCODE_SYSTEM below can GC and/or relocate the Lisp /* ENCODE_SYSTEM below can GC and/or relocate the
String whose data pointer might be passed to us in M. So Lisp data, so make sure we don't use it here. */
we use a local copy. */ eassert (relocatable_string_data_p (m) != 1);
char *fmt = xstrdup (m);
   
if (noninteractive_need_newline) if (noninteractive_need_newline)
putc ('\n', stderr); putc ('\n', stderr);
noninteractive_need_newline = 0; noninteractive_need_newline = 0;
fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string))); fprintf (stderr, m, SDATA (ENCODE_SYSTEM (string)));
if (!cursor_in_echo_area) if (!cursor_in_echo_area)
fprintf (stderr, "\n"); fprintf (stderr, "\n");
fflush (stderr); fflush (stderr);
xfree (fmt);
} }
} }
else if (INTERACTIVE) else if (INTERACTIVE)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment