* Append the backtrace to the given PipeProtoChunk or the syslogger file or stderr. * * We can not use the default backtrace_symbols since it calls malloc, which * is not async-safe, to allocate space for symbols. Even though we don't * really support async-safe error logging yet, the malloc has caused several * deadlock issues in the past, we should avoid using them in our error handler. *
| 3779 | * Otherwise, write to stderr. |
| 3780 | */ |
| 3781 | static void |
| 3782 | append_stacktrace(PipeProtoChunk *buffer, StringInfo append, void *const *stackarray, |
| 3783 | int stacksize, bool amsyslogger) |
| 3784 | { |
| 3785 | #if !defined(WIN32) && !defined(_AIX) |
| 3786 | int stack_no; |
| 3787 | char symbol[SYMBOL_SIZE]; /* a reasonable size for a symbol */ |
| 3788 | Dl_info dli; |
| 3789 | int symbol_len; |
| 3790 | |
| 3791 | |
| 3792 | FILE * fd; |
| 3793 | bool fd_ok = false; |
| 3794 | char cmd[CMD_BUFFER_SIZE]; |
| 3795 | char cmdresult[STACK_DEPTH_MAX][SYMBOL_SIZE]; |
| 3796 | char addrtxt[ADDRESS_SIZE]; |
| 3797 | |
| 3798 | #if defined(__darwin__) |
| 3799 | const char * prog = "atos -o"; |
| 3800 | #else |
| 3801 | const char * prog = "addr2line -s -e"; |
| 3802 | #endif |
| 3803 | |
| 3804 | static bool in_translate_stacktrace = false; |
| 3805 | bool addr2line_ok = gp_log_stack_trace_lines; |
| 3806 | |
| 3807 | if (stacksize == 0) |
| 3808 | return; |
| 3809 | |
| 3810 | |
| 3811 | if (!in_translate_stacktrace && addr2line_ok) |
| 3812 | { |
| 3813 | /* |
| 3814 | * Keep a record that we are doing this work, so if we crash during it, we don't |
| 3815 | * try to do it again when we recurse back here, |
| 3816 | */ |
| 3817 | in_translate_stacktrace = true; |
| 3818 | |
| 3819 | snprintf(cmd,sizeof(cmd),"%s %s ",prog,my_exec_path); |
| 3820 | |
| 3821 | for (stack_no = 0; stack_no < stacksize && stack_no < 100; stack_no++) |
| 3822 | { |
| 3823 | cmdresult[stack_no][0] = '\0'; /* clear this array for later */ |
| 3824 | snprintf(addrtxt, sizeof(addrtxt),"%p ",stackarray[stack_no]); |
| 3825 | |
| 3826 | Assert(sizeof(cmd) > strlen(cmd)); |
| 3827 | strncat(cmd, addrtxt, sizeof(cmd) - strlen(cmd) - 1); |
| 3828 | } |
| 3829 | |
| 3830 | cmdresult[0][0] = '\0'; |
| 3831 | fd = popen(cmd,"r"); |
| 3832 | if (fd != NULL) |
| 3833 | fd_ok = true; |
| 3834 | |
| 3835 | if (fd_ok) |
| 3836 | { |
| 3837 | for (stack_no = 0; stack_no < stacksize && stack_no < STACK_DEPTH_MAX; stack_no++) |
| 3838 | { |
no test coverage detected