Commit 29dd634a authored by Sergei Golubchik's avatar Sergei Golubchik

dbug: correct trace for DBUG_RETURN(func()); -- gcc only

when func1 calls func2 from DBUG_RETURN, dbug shows the trace as
| > func1
| < func1
| > func2
| < func2
because DBUG_LEAVE happens before func2(). Change that to invoke
DBUG_LEAVE when the local variable goes out of scope. This uses
gcc specific __attribute__((cleanup)).
parent 8f60656f
...@@ -320,6 +320,7 @@ IF(MSVC_VERSION GREATER 1310) ...@@ -320,6 +320,7 @@ IF(MSVC_VERSION GREATER 1310)
SET(HAVE_VSNPRINTF 1 CACHE INTERNAL "") SET(HAVE_VSNPRINTF 1 CACHE INTERNAL "")
ENDIF() ENDIF()
SET(HAVE_WEAK_SYMBOL CACHE INTERNAL "") SET(HAVE_WEAK_SYMBOL CACHE INTERNAL "")
SET(HAVE_ATTRIBUTE_CLEANUP CACHE INTERNAL "")
SET(HAVE_WORDS_BIGENDIAN TRUE CACHE INTERNAL "") SET(HAVE_WORDS_BIGENDIAN TRUE CACHE INTERNAL "")
SET(WORDS_BIGENDIAN CACHE INTERNAL "") SET(WORDS_BIGENDIAN CACHE INTERNAL "")
SET(HAVE__S_IFIFO 1 CACHE INTERNAL "") SET(HAVE__S_IFIFO 1 CACHE INTERNAL "")
......
...@@ -465,7 +465,7 @@ ...@@ -465,7 +465,7 @@
#cmakedefine HAVE_WEAK_SYMBOL 1 #cmakedefine HAVE_WEAK_SYMBOL 1
#cmakedefine HAVE_ABI_CXA_DEMANGLE 1 #cmakedefine HAVE_ABI_CXA_DEMANGLE 1
#cmakedefine HAVE_ATTRIBUTE_CLEANUP 1
#cmakedefine HAVE_POSIX_SIGNALS 1 #cmakedefine HAVE_POSIX_SIGNALS 1
#cmakedefine HAVE_BSD_SIGNALS 1 #cmakedefine HAVE_BSD_SIGNALS 1
......
...@@ -910,6 +910,14 @@ CHECK_C_SOURCE_COMPILES(" ...@@ -910,6 +910,14 @@ CHECK_C_SOURCE_COMPILES("
HAVE_WEAK_SYMBOL HAVE_WEAK_SYMBOL
) )
CHECK_C_SOURCE_COMPILES("
void foo(int *x) { }
int main() {
int a __attribute__((cleanup(foo)));
return 0;
}"
HAVE_ATTRIBUTE_CLEANUP
)
CHECK_CXX_SOURCE_COMPILES(" CHECK_CXX_SOURCE_COMPILES("
#include <new> #include <new>
......
...@@ -1106,6 +1106,7 @@ void _db_enter_(const char *_func_, const char *_file_, ...@@ -1106,6 +1106,7 @@ void _db_enter_(const char *_func_, const char *_file_,
} }
save_errno= errno; save_errno= errno;
_stack_frame_->line= -1;
_stack_frame_->func= cs->func; _stack_frame_->func= cs->func;
_stack_frame_->file= cs->file; _stack_frame_->file= cs->file;
cs->func= _func_; cs->func= _func_;
...@@ -1161,14 +1162,17 @@ void _db_enter_(const char *_func_, const char *_file_, ...@@ -1161,14 +1162,17 @@ void _db_enter_(const char *_func_, const char *_file_,
* *
*/ */
void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_) void _db_return_(struct _db_stack_frame_ *_stack_frame_)
{ {
int save_errno=errno; int save_errno=errno;
uint _slevel_= _stack_frame_->level & ~TRACE_ON; uint _slevel_= _stack_frame_->level & ~TRACE_ON;
CODE_STATE *cs; CODE_STATE *cs;
get_code_state_or_return; get_code_state_or_return;
if (cs->framep != _stack_frame_) if (_stack_frame_->line == 0)
return;
if (_stack_frame_->line == -1 || cs->framep != _stack_frame_)
{ {
char buf[512]; char buf[512];
my_snprintf(buf, sizeof(buf), ERR_MISSING_RETURN, cs->func); my_snprintf(buf, sizeof(buf), ERR_MISSING_RETURN, cs->func);
...@@ -1183,7 +1187,7 @@ void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_) ...@@ -1183,7 +1187,7 @@ void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
{ {
if (!cs->locked) if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
DoPrefix(cs, _line_); DoPrefix(cs, _stack_frame_->line);
Indent(cs, cs->level); Indent(cs, cs->level);
(void) fprintf(cs->stack->out_file->file, "<%s\n", cs->func); (void) fprintf(cs->stack->out_file->file, "<%s\n", cs->func);
DbugFlush(cs); DbugFlush(cs);
......
...@@ -30,6 +30,7 @@ struct _db_stack_frame_ { ...@@ -30,6 +30,7 @@ struct _db_stack_frame_ {
const char *func; /* function name of the previous stack frame */ const char *func; /* function name of the previous stack frame */
const char *file; /* filename of the function of previous frame */ const char *file; /* filename of the function of previous frame */
uint level; /* this nesting level, highest bit enables tracing */ uint level; /* this nesting level, highest bit enables tracing */
int line; /* line of DBUG_RETURN */
struct _db_stack_frame_ *prev; /* pointer to the previous frame */ struct _db_stack_frame_ *prev; /* pointer to the previous frame */
}; };
...@@ -48,7 +49,7 @@ extern void _db_set_(const char *control); ...@@ -48,7 +49,7 @@ extern void _db_set_(const char *control);
extern void _db_set_init_(const char *control); extern void _db_set_init_(const char *control);
extern void _db_enter_(const char *_func_, const char *_file_, uint _line_, extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
struct _db_stack_frame_ *_stack_frame_); struct _db_stack_frame_ *_stack_frame_);
extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_); extern void _db_return_(struct _db_stack_frame_ *_stack_frame_);
extern void _db_pargs_(uint _line_,const char *keyword); extern void _db_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_(const char *format,...) extern void _db_doprnt_(const char *format,...)
ATTRIBUTE_FORMAT(printf, 1, 2); ATTRIBUTE_FORMAT(printf, 1, 2);
...@@ -63,12 +64,24 @@ extern void dbug_swap_code_state(void **code_state_store); ...@@ -63,12 +64,24 @@ extern void dbug_swap_code_state(void **code_state_store);
extern void dbug_free_code_state(void **code_state_store); extern void dbug_free_code_state(void **code_state_store);
extern const char* _db_get_func_(void); extern const char* _db_get_func_(void);
#define DBUG_LEAVE do { \
_db_stack_frame_.line= __LINE__; \
_db_return_ (&_db_stack_frame_); \
_db_stack_frame_.line= 0; \
} while(0)
#ifdef HAVE_ATTRIBUTE_CLEANUP
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_ __attribute__((cleanup(_db_return_))); \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
#define DBUG_RETURN(a1) do { _db_stack_frame_.line=__LINE__; return(a1);} while(0)
#define DBUG_VOID_RETURN do { _db_stack_frame_.line=__LINE__; return;} while(0)
#else
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \ #define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_) _db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_)
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0) #define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0) #define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
#endif
#define DBUG_EXECUTE(keyword,a1) \ #define DBUG_EXECUTE(keyword,a1) \
do {if (_db_keyword_(0, (keyword), 0)) { a1 }} while(0) do {if (_db_keyword_(0, (keyword), 0)) { a1 }} while(0)
#define DBUG_EXECUTE_IF(keyword,a1) \ #define DBUG_EXECUTE_IF(keyword,a1) \
......
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