Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8e68816

Browse files
committed
Be more robust when strerror() doesn't give a useful result.
glibc, at least, is capable of returning "???" instead of anything usefulif it doesn't like the setting of LC_CTYPE. If this happens, or in thepreviously-known case of strerror() returning an empty string, try toprint the C macro name for the error code ("EACCES" etc). Only if wedon't have the error code in our compiled-in list of popular error codes(which covers most though not quite all of what's called out in the POSIXspec) will we fall back to printing a numeric error code. This shouldsimplify debugging.Note that this functionality is currently only provided for %m in backendereport/elog messages. That may be sufficient, since we don't fool with thelocale environment in frontend clients, but it's foreseeable that we mightwant similar code in libpq for instance.There was some talk of back-patching this, but let's see how the buildfarmlikes it first. It seems likely that at least some of the POSIX-definederror code symbols don't exist on all platforms. I don't want to clutterthe entire list with #ifdefs, but we may need more than are here now.MauMau, edited by me
1 parentbb45c64 commit8e68816

File tree

1 file changed

+157
-4
lines changed

1 file changed

+157
-4
lines changed

‎src/backend/utils/error/elog.c

Lines changed: 157 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ static void send_message_to_server_log(ErrorData *edata);
173173
staticvoidsend_message_to_frontend(ErrorData*edata);
174174
staticchar*expand_fmt_string(constchar*fmt,ErrorData*edata);
175175
staticconstchar*useful_strerror(interrnum);
176+
staticconstchar*get_errno_symbol(interrnum);
176177
staticconstchar*error_severity(intelevel);
177178
staticvoidappend_with_tabs(StringInfobuf,constchar*str);
178179
staticboolis_log_level_output(intelevel,intlog_min_level);
@@ -3206,7 +3207,7 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
32063207
staticconstchar*
32073208
useful_strerror(interrnum)
32083209
{
3209-
/* this buffer is only used iferrno has a bogus value */
3210+
/* this buffer is only used ifstrerror() and get_errno_symbol() fail */
32103211
staticcharerrorstr_buf[48];
32113212
constchar*str;
32123213

@@ -3218,10 +3219,16 @@ useful_strerror(int errnum)
32183219
str=strerror(errnum);
32193220

32203221
/*
3221-
* Some strerror()s return an empty string for out-of-range errno. This is
3222-
* ANSI C spec compliant, but not exactly useful.
3222+
* Some strerror()s return an empty string for out-of-range errno.This
3223+
* is ANSI C spec compliant, but not exactly useful. Also, we may get
3224+
* back strings of question marks if libc cannot transcode the message to
3225+
* the codeset specified by LC_CTYPE. If we get nothing useful, first try
3226+
* get_errno_symbol(), and if that fails, print the numeric errno.
32233227
*/
3224-
if (str==NULL||*str=='\0')
3228+
if (str==NULL||*str=='\0'||*str=='?')
3229+
str=get_errno_symbol(errnum);
3230+
3231+
if (str==NULL)
32253232
{
32263233
snprintf(errorstr_buf,sizeof(errorstr_buf),
32273234
/*------
@@ -3234,6 +3241,152 @@ useful_strerror(int errnum)
32343241
returnstr;
32353242
}
32363243

3244+
/*
3245+
* Returns a symbol (e.g. "ENOENT") for an errno code.
3246+
* Returns NULL if the code is unrecognized.
3247+
*/
3248+
staticconstchar*
3249+
get_errno_symbol(interrnum)
3250+
{
3251+
switch (errnum)
3252+
{
3253+
caseE2BIG:
3254+
return"E2BIG";
3255+
caseEACCES:
3256+
return"EACCES";
3257+
caseEADDRINUSE:
3258+
return"EADDRINUSE";
3259+
caseEADDRNOTAVAIL:
3260+
return"EADDRNOTAVAIL";
3261+
caseEAFNOSUPPORT:
3262+
return"EAFNOSUPPORT";
3263+
#ifdefEAGAIN
3264+
caseEAGAIN:
3265+
return"EAGAIN";
3266+
#endif
3267+
caseEALREADY:
3268+
return"EALREADY";
3269+
caseEBADF:
3270+
return"EBADF";
3271+
caseEBADMSG:
3272+
return"EBADMSG";
3273+
caseEBUSY:
3274+
return"EBUSY";
3275+
caseECHILD:
3276+
return"ECHILD";
3277+
caseECONNABORTED:
3278+
return"ECONNABORTED";
3279+
caseECONNREFUSED:
3280+
return"ECONNREFUSED";
3281+
#ifdefECONNRESET
3282+
caseECONNRESET:
3283+
return"ECONNRESET";
3284+
#endif
3285+
caseEDEADLK:
3286+
return"EDEADLK";
3287+
caseEDOM:
3288+
return"EDOM";
3289+
caseEEXIST:
3290+
return"EEXIST";
3291+
caseEFAULT:
3292+
return"EFAULT";
3293+
caseEFBIG:
3294+
return"EFBIG";
3295+
caseEHOSTUNREACH:
3296+
return"EHOSTUNREACH";
3297+
caseEIDRM:
3298+
return"EIDRM";
3299+
caseEINPROGRESS:
3300+
return"EINPROGRESS";
3301+
caseEINTR:
3302+
return"EINTR";
3303+
caseEINVAL:
3304+
return"EINVAL";
3305+
caseEIO:
3306+
return"EIO";
3307+
caseEISCONN:
3308+
return"EISCONN";
3309+
caseEISDIR:
3310+
return"EISDIR";
3311+
caseELOOP:
3312+
return"ELOOP";
3313+
caseEMFILE:
3314+
return"EMFILE";
3315+
caseEMLINK:
3316+
return"EMLINK";
3317+
caseEMSGSIZE:
3318+
return"EMSGSIZE";
3319+
caseENAMETOOLONG:
3320+
return"ENAMETOOLONG";
3321+
caseENFILE:
3322+
return"ENFILE";
3323+
caseENOBUFS:
3324+
return"ENOBUFS";
3325+
caseENODEV:
3326+
return"ENODEV";
3327+
caseENOENT:
3328+
return"ENOENT";
3329+
caseENOEXEC:
3330+
return"ENOEXEC";
3331+
caseENOMEM:
3332+
return"ENOMEM";
3333+
caseENOSPC:
3334+
return"ENOSPC";
3335+
caseENOSYS:
3336+
return"ENOSYS";
3337+
caseENOTCONN:
3338+
return"ENOTCONN";
3339+
caseENOTDIR:
3340+
return"ENOTDIR";
3341+
#if defined(ENOTEMPTY)&& (ENOTEMPTY!=EEXIST)/* same code on AIX */
3342+
caseENOTEMPTY:
3343+
return"ENOTEMPTY";
3344+
#endif
3345+
caseENOTSOCK:
3346+
return"ENOTSOCK";
3347+
#ifdefENOTSUP
3348+
caseENOTSUP:
3349+
return"ENOTSUP";
3350+
#endif
3351+
caseENOTTY:
3352+
return"ENOTTY";
3353+
caseENXIO:
3354+
return"ENXIO";
3355+
#if defined(EOPNOTSUPP)&& (!defined(ENOTSUP)|| (EOPNOTSUPP!=ENOTSUP))
3356+
caseEOPNOTSUPP:
3357+
return"EOPNOTSUPP";
3358+
#endif
3359+
caseEOVERFLOW:
3360+
return"EOVERFLOW";
3361+
caseEPERM:
3362+
return"EPERM";
3363+
caseEPIPE:
3364+
return"EPIPE";
3365+
caseEPROTONOSUPPORT:
3366+
return"EPROTONOSUPPORT";
3367+
caseERANGE:
3368+
return"ERANGE";
3369+
#ifdefEROFS
3370+
caseEROFS:
3371+
return"EROFS";
3372+
#endif
3373+
caseESRCH:
3374+
return"ESRCH";
3375+
caseETIMEDOUT:
3376+
return"ETIMEDOUT";
3377+
caseETXTBSY:
3378+
return"ETXTBSY";
3379+
#if defined(EWOULDBLOCK)&& (!defined(EAGAIN)|| (EWOULDBLOCK!=EAGAIN))
3380+
caseEWOULDBLOCK:
3381+
return"EWOULDBLOCK";
3382+
#endif
3383+
caseEXDEV:
3384+
return"EXDEV";
3385+
}
3386+
3387+
returnNULL;
3388+
}
3389+
32373390

32383391
/*
32393392
* error_severity --- get localized string representing elevel

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp