PostgreSQL Source Code: src/backend/utils/error/elog.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

56

57#include <fcntl.h>

60#include <signal.h>

61#include <ctype.h>

62#ifdef HAVE_SYSLOG

63#include <syslog.h>

64#endif

65#ifdef HAVE_EXECINFO_H

66#include <execinfo.h>

67#endif

68

87

88

89

90#undef _

91#define _(x) err_gettext(x)

92

93

94

96

98

99

100

101

102

103

104

105

107

108

115

116

118

119#ifdef HAVE_SYSLOG

120

121

122

123

124

125

126

127

128#ifndef PG_SYSLOG_LIMIT

129#define PG_SYSLOG_LIMIT 900

130#endif

131

132static bool openlog_done = false;

133static char *syslog_ident = NULL;

135

136static void write_syslog(int level, const char *line);

137#endif

138

139#ifdef WIN32

140static void write_eventlog(int level, const char *line, int len);

141#endif

142

143

144#define ERRORDATA_STACK_SIZE 5

145

147

149

151

152

153

154

155

158

159#define FORMATTED_TS_LEN 128

162

163

164

165#define CHECK_STACK_DEPTH() \

166 do { \

167 if (errordata_stack_depth < 0) \

168 { \

169 errordata_stack_depth = -1; \

170 ereport(ERROR, (errmsg_internal("errstart was not called"))); \

171 } \

172 } while (0)

173

174

179 const char *filename, int lineno,

191

192

193

194

195

196

197

198

199

200

201static inline bool

203{

205 {

206 if (log_min_level == LOG || log_min_level <= ERROR)

207 return true;

208 }

210 {

211

212 return false;

213 }

214 else if (log_min_level == LOG)

215 {

216

217 if (elevel >= FATAL)

218 return true;

219 }

220

221 else if (elevel >= log_min_level)

222 return true;

223

224 return false;

225}

226

227

228

229

230

231

232

233

234

235static inline bool

237{

239}

240

241

242

243

244static inline bool

246{

248 {

249

250

251

252

253

254

256 return (elevel >= ERROR);

257 else

259 }

260 return false;

261}

262

263

264

265

266

267

268

269

270

271

272bool

274{

275

276

277

278 if (elevel >= ERROR ||

281 return true;

282 return false;

283}

284

285

286

287

288

289

290

291

292

293bool

295{

296

298}

299

300

301

302

303

304

305static inline const char *

307{

308#ifdef ENABLE_NLS

310 return str;

311 else

313#else

314 return str;

315#endif

316}

317

318

319

320

321

322

323

324

325

328{

329 return errstart(elevel, domain);

330}

331

332

333

334

335

336

337

338

339

340

341

342bool

344{

346 bool output_to_server;

347 bool output_to_client = false;

348 int i;

349

350

351

352

353

354 if (elevel >= ERROR)

355 {

356

357

358

359

362

363

364

365

366

367

368

369

370

371

372

373

374

375 if (elevel == ERROR)

376 {

381 }

382

383

384

385

386

387

388

389

390

393 }

394

395

396

397

398

399

402 if (elevel < ERROR && !output_to_server && !output_to_client)

403 return false;

404

405

406

407

408

410 {

411

412 write_stderr("error occurred before error message processing is available\n");

413 exit(2);

414 }

415

416

417

418

419

421 {

422

423

424

425

426

428

429

430

431

432

433

434

436 {

439 }

440 }

441

442

444 edata->elevel = elevel;

448

449 if (elevel >= ERROR)

450 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;

451 else if (elevel >= WARNING)

453 else

454 edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;

455

456

457

458

460

462 return true;

463}

464

465

466

467

468

469

470

471

472

473void

475{

477 int elevel;

480

483

484

486

487 elevel = edata->elevel;

488

489

490

491

492

494

495

501

502

503

504

505

506

508 econtext != NULL;

509 econtext = econtext->previous)

511

512

513

514

515

516 if (elevel == ERROR)

517 {

518

519

520

521

522

523

524

525

526

527

530

532

533

534

535

536

537

540 }

541

542

544

545

548

549

552

553

554

555

556 if (elevel == FATAL)

557 {

558

559

560

561

562

563

566

567

568

569

570

571

572

573 fflush(NULL);

574

575

576

577

578

581

582

583

584

585

586

588 }

589

590 if (elevel >= PANIC)

591 {

592

593

594

595

596

597

598

599 fflush(NULL);

600 abort();

601 }

602

603

604

605

606

607

609}

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629bool

631{

634

635

636

637

638

641

642

645

646

648 return false;

649

650

651

652

653

655

656

658 edata->elevel = LOG;

660

661 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;

662

663

664

665

666

667

669

671 return true;

672}

673

674

675

676

677

678

679

680

681void

684{

687

688

690

691

692

693

694

696 {

699 }

700

701

702

703

704

706

707

709

710

712

713

714

715

716

717

718

719

720

721

722

723

726

727

730}

731

732

733

734

735

736

737

738

739

740

741

742

743

744

745

746

747

748

749

750

753{

755

756

759 {

760

763 }

764

765

767 memset(edata, 0, sizeof(ErrorData));

768

769

771

772 return edata;

773}

774

775

776

777

778static void

780{

781

783

785}

786

787

788

789

790

791

792

793

794

795static void

797 const char *filename, int lineno,

799{

801 {

802 const char *slash;

803

804

805 slash = strrchr(filename, '/');

806 if (slash)

808

809 slash = strrchr(filename, '\\');

810 if (slash)

812 }

813

815 edata->lineno = lineno;

817}

818

819

820

821

822

823

824

825static bool

827{

828 const char *p;

829

831 return false;

832

834 for (;;)

835 {

836 if (*p == '\0')

837 break;

838

839 if (strcmp(funcname, p) == 0)

840 return true;

841 p += strlen(p) + 1;

842 }

843

844 return false;

845}

846

847

848

849

850

851

852

853int

855{

857

858

860

862

863 return 0;

864}

865

866

867

868

869

870

871

872

873

874

875

876int

878{

880

881

883

885 {

886

887 case EPERM:

888 case EACCES:

889#ifdef EROFS

890 case EROFS:

891#endif

892 edata->sqlerrcode = ERRCODE_INSUFFICIENT_PRIVILEGE;

893 break;

894

895

896 case ENOENT:

897 edata->sqlerrcode = ERRCODE_UNDEFINED_FILE;

898 break;

899

900

901 case EEXIST:

902 edata->sqlerrcode = ERRCODE_DUPLICATE_FILE;

903 break;

904

905

906 case ENOTDIR:

907 case EISDIR:

908 case ENOTEMPTY:

909 edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;

910 break;

911

912

913 case ENOSPC:

914 edata->sqlerrcode = ERRCODE_DISK_FULL;

915 break;

916

917 case ENOMEM:

918 edata->sqlerrcode = ERRCODE_OUT_OF_MEMORY;

919 break;

920

921 case ENFILE:

922 case EMFILE:

923 edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;

924 break;

925

926

927 case EIO:

928 edata->sqlerrcode = ERRCODE_IO_ERROR;

929 break;

930

931 case ENAMETOOLONG:

932 edata->sqlerrcode = ERRCODE_FILE_NAME_TOO_LONG;

933 break;

934

935

936 default:

937 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;

938 break;

939 }

940

941 return 0;

942}

943

944

945

946

947

948

949

950

951

952

953int

955{

957

958

960

962 {

963

965 edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;

966 break;

967

968

969 default:

970 edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;

971 break;

972 }

973

974 return 0;

975}

976

977

978

979

980

981

982

983

984

985

986

987

988

989

990#define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit) \

991 { \

992 StringInfoData buf; \

993 \

994 if ((translateit) && !in_error_recursion_trouble()) \

995 fmt = dgettext((domain), fmt); \

996 initStringInfo(&buf); \

997 if ((appendval) && edata->targetfield) { \

998 appendStringInfoString(&buf, edata->targetfield); \

999 appendStringInfoChar(&buf, '\n'); \

1000 } \

1001 \

1002 for (;;) \

1003 { \

1004 va_list args; \

1005 int needed; \

1006 errno = edata->saved_errno; \

1007 va_start(args, fmt); \

1008 needed = appendStringInfoVA(&buf, fmt, args); \

1009 va_end(args); \

1010 if (needed == 0) \

1011 break; \

1012 enlargeStringInfo(&buf, needed); \

1013 } \

1014 \

1015 if (edata->targetfield) \

1016 pfree(edata->targetfield); \

1017 edata->targetfield = pstrdup(buf.data); \

1018 pfree(buf.data); \

1019 }

1020

1021

1022

1023

1024

1025

1026#define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval) \

1027 { \

1028 const char *fmt; \

1029 StringInfoData buf; \

1030 \

1031 if (!in_error_recursion_trouble()) \

1032 fmt = dngettext((domain), fmt_singular, fmt_plural, n); \

1033 else \

1034 fmt = (n == 1 ? fmt_singular : fmt_plural); \

1035 initStringInfo(&buf); \

1036 if ((appendval) && edata->targetfield) { \

1037 appendStringInfoString(&buf, edata->targetfield); \

1038 appendStringInfoChar(&buf, '\n'); \

1039 } \

1040 \

1041 for (;;) \

1042 { \

1043 va_list args; \

1044 int needed; \

1045 errno = edata->saved_errno; \

1046 va_start(args, n); \

1047 needed = appendStringInfoVA(&buf, fmt, args); \

1048 va_end(args); \

1049 if (needed == 0) \

1050 break; \

1051 enlargeStringInfo(&buf, needed); \

1052 } \

1053 \

1054 if (edata->targetfield) \

1055 pfree(edata->targetfield); \

1056 edata->targetfield = pstrdup(buf.data); \

1057 pfree(buf.data); \

1058 }

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070int

1072{

1075

1079

1082

1085 return 0;

1086}

1087

1088

1089

1090

1091

1092int

1094{

1097

1101

1103

1106

1107 return 0;

1108}

1109

1110

1111

1112

1113

1114

1115

1116static void

1118{

1120

1122

1123#ifdef HAVE_BACKTRACE_SYMBOLS

1124 {

1125 void *buf[100];

1126 int nframes;

1127 char **strfrms;

1128

1130 strfrms = backtrace_symbols(buf, nframes);

1131 if (strfrms == NULL)

1132 return;

1133

1134 for (int i = num_skip; i < nframes; i++)

1136 free(strfrms);

1137 }

1138#else

1140 "backtrace generation is not supported by this installation");

1141#endif

1142

1144}

1145

1146

1147

1148

1149

1150

1151

1152

1153

1154

1155

1156

1157int

1159{

1162

1166

1169

1172 return 0;

1173}

1174

1175

1176

1177

1178

1179

1180int

1182 unsigned long n,...)

1183{

1186

1190

1193

1196 return 0;

1197}

1198

1199

1200

1201

1202

1203int

1205{

1208

1212

1214

1217 return 0;

1218}

1219

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230int

1232{

1235

1239

1241

1244 return 0;

1245}

1246

1247

1248

1249

1250

1251int

1253{

1256

1260

1262

1265 return 0;

1266}

1267

1268

1269

1270

1271

1272int

1274 unsigned long n,...)

1275{

1278

1282

1284

1287 return 0;

1288}

1289

1290

1291

1292

1293

1294

1295int

1297 unsigned long n,...)

1298{

1301

1305

1307

1310 return 0;

1311}

1312

1313

1314

1315

1316

1317int

1319{

1322

1326

1328

1331 return 0;

1332}

1333

1334

1335

1336

1337

1338

1339int

1341{

1344

1348

1350

1353 return 0;

1354}

1355

1356

1357

1358

1359

1360int

1362 unsigned long n,...)

1363{

1366

1370

1372

1375 return 0;

1376}

1377

1378

1379

1380

1381

1382

1383

1384

1385

1386int

1388{

1391

1395

1397

1400 return 0;

1401}

1402

1403

1404

1405

1406

1407

1408

1409

1410

1411

1412int

1414{

1416

1417

1419

1420

1422

1423 return 0;

1424}

1425

1426

1427

1428

1429

1430

1431

1432int

1434{

1436

1437

1439

1441

1442 return 0;

1443}

1444

1445

1446

1447

1448

1449

1450

1451int

1453{

1455

1456

1458

1460

1461 return 0;

1462}

1463

1464

1465

1466

1467int

1469{

1471

1472

1474

1476

1477 return 0;

1478}

1479

1480

1481

1482

1483int

1485{

1487

1488

1490

1492

1493 return 0;

1494}

1495

1496

1497

1498

1499

1500

1501

1502

1503int

1505{

1507

1508

1510

1512 {

1515 }

1516

1517 if (query)

1519

1520 return 0;

1521}

1522

1523

1524

1525

1526

1527

1528

1529

1530

1531

1532

1533int

1535{

1537

1538

1540

1541 switch (field)

1542 {

1545 break;

1548 break;

1551 break;

1554 break;

1557 break;

1558 default:

1559 elog(ERROR, "unsupported ErrorData field id: %d", field);

1560 break;

1561 }

1562

1563 return 0;

1564}

1565

1566

1567

1568

1569static void

1571{

1572 Assert(*ptr == NULL);

1574}

1575

1576

1577

1578

1579

1580

1581

1582int

1584{

1586

1587

1589

1591}

1592

1593

1594

1595

1596

1597

1598

1599int

1601{

1603

1604

1606

1608}

1609

1610

1611

1612

1613

1614

1615

1616int

1618{

1620

1621

1623

1625}

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636

1637

1638

1639

1640

1641

1642

1643

1644

1645

1648

1649void

1651{

1652

1654

1656}

1657

1658char *

1660{

1664

1665

1666 edata = &errdata;

1668

1670

1672

1674

1677

1679

1681}

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691void

1693{

1696

1700

1701

1702

1703

1704

1705

1708

1709

1710

1711

1712

1713

1714

1715

1716

1717

1718

1719

1720

1721

1722

1723

1724

1725

1726

1727

1729 (*emit_log_hook) (edata);

1730

1731

1734

1735

1738

1741}

1742

1743

1744

1745

1746

1747

1748

1749

1752{

1755

1756

1757

1758

1759

1761

1763

1764

1766 memcpy(newedata, edata, sizeof(ErrorData));

1767

1768

1769

1770

1771

1772

1773

1774

1779 if (newedata->domain)

1785 if (newedata->detail)

1789 if (newedata->hint)

1809

1810

1812

1813 return newedata;

1814}

1815

1816

1817

1818

1819

1820

1821

1822void

1824{

1827}

1828

1829

1830

1831

1832

1833

1834static void

1836{

1843 if (edata->hint)

1861}

1862

1863

1864

1865

1866

1867

1868

1869

1870

1871void

1873{

1874

1875

1876

1877

1878

1879

1882

1884}

1885

1886

1887

1888

1889

1890

1891

1892

1893

1894

1895

1896

1897

1898

1899void

1901{

1904

1906 return;

1907

1911

1912

1921 if (edata->hint)

1927

1942

1945

1946

1948}

1949

1950

1951

1952

1953

1954

1955

1956

1957

1958void

1960{

1962

1964

1965

1968

1970 memcpy(newedata, edata, sizeof(ErrorData));

1971

1972

1975 if (newedata->detail)

1979 if (newedata->hint)

1997

1998

2000

2003}

2004

2005

2006

2007

2008void

2010{

2011

2014 else

2015 {

2016

2017

2018

2019

2020

2021

2022

2023

2025

2029

2030

2031

2032

2033

2036

2037

2038

2039

2040

2041

2043

2045 }

2046

2047

2049}

2050

2051

2052

2053

2054

2055

2056

2057

2058

2059

2060

2061

2062

2063char *

2065{

2068

2069

2070

2071

2073

2075

2076

2077

2078

2079

2081

2082

2083

2084

2085

2086

2087

2088

2089

2091 econtext != NULL;

2092 econtext = econtext->previous)

2094

2095

2096

2097

2098

2099

2100

2103

2104

2105

2106

2107

2109}

2110

2111

2112

2113

2114

2115void

2117{

2118 int fd,

2119 istty;

2120

2122 {

2123

2124

2125

2126

2127

2128 if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,

2129 0666)) < 0)

2133 istty = isatty(fd);

2135

2136

2137

2138

2142 errmsg("could not reopen file \"%s\" as stderr: %m",

2144

2145

2146

2147

2148

2149

2150

2155 errmsg("could not reopen file \"%s\" as stdout: %m",

2157 }

2158}

2159

2160

2161

2162

2163

2164

2165

2166

2167

2168

2169

2170

2171bool

2173{

2174 int newvallen = strlen(*newval);

2175 char *someval;

2176 int validlen;

2177 int i;

2178 int j;

2179

2180

2181

2182

2183

2184 validlen = strspn(*newval,

2185 "0123456789_"

2186 "abcdefghijklmnopqrstuvwxyz"

2187 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

2188 ", \n\t");

2189 if (validlen != newvallen)

2190 {

2192 return false;

2193 }

2194

2195 if (*newval[0] == '\0')

2196 {

2197 *extra = NULL;

2198 return true;

2199 }

2200

2201

2202

2203

2204

2205

2207 if (!someval)

2208 return false;

2209 for (i = 0, j = 0; i < newvallen; i++)

2210 {

2211 if ((*newval)[i] == ',')

2212 someval[j++] = '\0';

2213 else if ((*newval)[i] == ' ' ||

2216 ;

2217 else

2218 someval[j++] = (*newval)[i];

2219 }

2220

2221

2222 someval[j] = '\0';

2223 someval[j + 1] = '\0';

2224

2225 *extra = someval;

2226 return true;

2227}

2228

2229

2230

2231

2232void

2234{

2236}

2237

2238

2239

2240

2241bool

2243{

2244 char *rawstring;

2245 List *elemlist;

2247 int newlogdest = 0;

2248 int *myextra;

2249

2250

2252

2253

2255 {

2256

2258 pfree(rawstring);

2260 return false;

2261 }

2262

2263 foreach(l, elemlist)

2264 {

2265 char *tok = (char *) lfirst(l);

2266

2273#ifdef HAVE_SYSLOG

2276#endif

2277#ifdef WIN32

2280#endif

2281 else

2282 {

2284 pfree(rawstring);

2286 return false;

2287 }

2288 }

2289

2290 pfree(rawstring);

2292

2294 if (!myextra)

2295 return false;

2296 *myextra = newlogdest;

2297 *extra = myextra;

2298

2299 return true;

2300}

2301

2302

2303

2304

2305void

2307{

2309}

2310

2311

2312

2313

2314void

2316{

2317#ifdef HAVE_SYSLOG

2318

2319

2320

2321

2322

2323

2324

2325

2326

2327

2328 if (syslog_ident == NULL || strcmp(syslog_ident, newval) != 0)

2329 {

2330 if (openlog_done)

2331 {

2332 closelog();

2333 openlog_done = false;

2334 }

2335 free(syslog_ident);

2336 syslog_ident = strdup(newval);

2337

2338 }

2339#endif

2340

2341}

2342

2343

2344

2345

2346void

2348{

2349#ifdef HAVE_SYSLOG

2350

2351

2352

2354 {

2355 if (openlog_done)

2356 {

2357 closelog();

2358 openlog_done = false;

2359 }

2361 }

2362#endif

2363

2364}

2365

2366#ifdef HAVE_SYSLOG

2367

2368

2369

2370

2371static void

2372write_syslog(int level, const char *line)

2373{

2374 static unsigned long seq = 0;

2375

2376 int len;

2377 const char *nlpos;

2378

2379

2380 if (!openlog_done)

2381 {

2382 openlog(syslog_ident ? syslog_ident : "postgres",

2383 LOG_PID | LOG_NDELAY | LOG_NOWAIT,

2385 openlog_done = true;

2386 }

2387

2388

2389

2390

2391

2392 seq++;

2393

2394

2395

2396

2397

2398

2399

2400

2401

2402 len = strlen(line);

2403 nlpos = strchr(line, '\n');

2405 {

2406 int chunk_nr = 0;

2407

2408 while (len > 0)

2409 {

2410 char buf[PG_SYSLOG_LIMIT + 1];

2411 int buflen;

2412 int i;

2413

2414

2415 if (line[0] == '\n')

2416 {

2417 line++;

2419

2420 nlpos = strchr(line, '\n');

2421 continue;

2422 }

2423

2424

2425 if (nlpos != NULL)

2426 buflen = nlpos - line;

2427 else

2428 buflen = len;

2429 buflen = Min(buflen, PG_SYSLOG_LIMIT);

2430 memcpy(buf, line, buflen);

2431 buf[buflen] = '\0';

2432

2433

2435 if (buflen <= 0)

2436 return;

2437 buf[buflen] = '\0';

2438

2439

2440 if (line[buflen] != '\0' &&

2441 !isspace((unsigned char) line[buflen]))

2442 {

2443

2444 i = buflen - 1;

2445 while (i > 0 && !isspace((unsigned char) buf[i]))

2446 i--;

2447

2448 if (i > 0)

2449 {

2450 buflen = i;

2451 buf[i] = '\0';

2452 }

2453 }

2454

2455 chunk_nr++;

2456

2458 syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);

2459 else

2460 syslog(level, "[%d] %s", chunk_nr, buf);

2461

2462 line += buflen;

2463 len -= buflen;

2464 }

2465 }

2466 else

2467 {

2468

2470 syslog(level, "[%lu] %s", seq, line);

2471 else

2472 syslog(level, "%s", line);

2473 }

2474}

2475#endif

2476

2477#ifdef WIN32

2478

2479

2480

2481

2482

2483static int

2484GetACPEncoding(void)

2485{

2487

2489 encoding = pg_codepage_to_encoding(GetACP());

2490

2492}

2493

2494

2495

2496

2497static void

2498write_eventlog(int level, const char *line, int len)

2499{

2500 WCHAR *utf16;

2501 int eventlevel = EVENTLOG_ERROR_TYPE;

2502 static HANDLE evtHandle = INVALID_HANDLE_VALUE;

2503

2504 if (evtHandle == INVALID_HANDLE_VALUE)

2505 {

2506 evtHandle = RegisterEventSource(NULL,

2508 if (evtHandle == NULL)

2509 {

2510 evtHandle = INVALID_HANDLE_VALUE;

2511 return;

2512 }

2513 }

2514

2515 switch (level)

2516 {

2522 case LOG:

2526 eventlevel = EVENTLOG_INFORMATION_TYPE;

2527 break;

2530 eventlevel = EVENTLOG_WARNING_TYPE;

2531 break;

2535 default:

2536 eventlevel = EVENTLOG_ERROR_TYPE;

2537 break;

2538 }

2539

2540

2541

2542

2543

2544

2545

2546

2547

2548

2549

2550

2551

2552

2556 {

2557 utf16 = pgwin32_message_to_UTF16(line, len, NULL);

2558 if (utf16)

2559 {

2560 ReportEventW(evtHandle,

2561 eventlevel,

2562 0,

2563 0,

2564 NULL,

2565 1,

2566 0,

2567 (LPCWSTR *) &utf16,

2568 NULL);

2569

2570

2572 return;

2573 }

2574 }

2575 ReportEventA(evtHandle,

2576 eventlevel,

2577 0,

2578 0,

2579 NULL,

2580 1,

2581 0,

2582 &line,

2583 NULL);

2584}

2585#endif

2586

2587static void

2589{

2590 int rc;

2591

2592#ifdef WIN32

2593

2594

2595

2596

2597

2598

2599

2600

2601

2602

2603

2604

2605

2606

2607

2608

2609

2610

2614 {

2615 WCHAR *utf16;

2616 int utf16len;

2617

2618 utf16 = pgwin32_message_to_UTF16(line, len, &utf16len);

2619 if (utf16 != NULL)

2620 {

2621 HANDLE stdHandle;

2622 DWORD written;

2623

2624 stdHandle = GetStdHandle(STD_ERROR_HANDLE);

2625 if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))

2626 {

2628 return;

2629 }

2630

2631

2632

2633

2634

2636 }

2637 }

2638#else

2639

2640

2641

2642

2643

2644

2645

2646

2647#endif

2648

2649

2650

2651

2652

2653 rc = write(fileno(stderr), line, len);

2654 (void) rc;

2655}

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665char *

2667{

2669 char msbuf[13];

2670

2671

2674

2676 {

2679 }

2680

2682

2683

2684

2685

2686

2687

2689

2690 "%Y-%m-%d %H:%M:%S %Z",

2692

2693

2696

2698}

2699

2700

2701

2702

2703void

2705{

2707}

2708

2709

2710

2711

2712

2713

2714

2715char *

2717{

2719

2720

2723

2724

2725

2726

2727

2728

2730 "%Y-%m-%d %H:%M:%S %Z",

2732

2734}

2735

2736

2737

2738

2739bool

2741{

2742

2744 return false;

2745

2746

2748 return false;

2749

2750

2752 return false;

2753

2754 return true;

2755}

2756

2757

2758

2759

2760

2761

2762const char *

2764{

2765 const char *backend_type_str;

2766

2768 backend_type_str = "postmaster";

2771 else

2773

2774 return backend_type_str;

2775}

2776

2777

2778

2779

2780

2781

2782

2783

2784static const char *

2786{

2787 int paddingsign = 1;

2788 int padding = 0;

2789

2790 if (*p == '-')

2791 {

2792 p++;

2793

2794 if (*p == '\0')

2795 return NULL;

2796 paddingsign = -1;

2797 }

2798

2799

2800 while (*p >= '0' && *p <= '9')

2801 padding = padding * 10 + (*p++ - '0');

2802

2803

2804 if (*p == '\0')

2805 return NULL;

2806

2807 padding *= paddingsign;

2808 *ppadding = padding;

2809 return p;

2810}

2811

2812

2813

2814

2815static void

2817{

2819}

2820

2821

2822

2823

2824void

2826{

2827

2828 static long log_line_number = 0;

2829

2830

2831 static int log_my_pid = 0;

2832 int padding;

2833 const char *p;

2834

2835

2836

2837

2838

2839

2840

2842 {

2843 log_line_number = 0;

2846 }

2847 log_line_number++;

2848

2850 return;

2851

2852 for (p = format; *p != '\0'; p++)

2853 {

2854 if (*p != '%')

2855 {

2856

2858 continue;

2859 }

2860

2861

2862 p++;

2863 if (*p == '\0')

2864 break;

2865 else if (*p == '%')

2866 {

2867

2869 continue;

2870 }

2871

2872

2873

2874

2875

2876

2877

2878

2879

2880

2881

2882

2883

2884

2885

2886

2887 if (*p > '9')

2888 padding = 0;

2890 break;

2891

2892

2893 switch (*p)

2894 {

2895 case 'a':

2897 {

2899

2900 if (appname == NULL || *appname == '\0')

2901 appname = _("[unknown]");

2902 if (padding != 0)

2904 else

2906 }

2907 else if (padding != 0)

2909 padding > 0 ? padding : -padding);

2910

2911 break;

2912 case 'b':

2913 {

2915

2916 if (padding != 0)

2918 else

2920 break;

2921 }

2922 case 'u':

2924 {

2926

2929 if (padding != 0)

2931 else

2933 }

2934 else if (padding != 0)

2936 padding > 0 ? padding : -padding);

2937 break;

2938 case 'd':

2940 {

2942

2944 dbname = _("[unknown]");

2945 if (padding != 0)

2947 else

2949 }

2950 else if (padding != 0)

2952 padding > 0 ? padding : -padding);

2953 break;

2954 case 'c':

2955 if (padding != 0)

2956 {

2957 char strfbuf[128];

2958

2962 }

2963 else

2965 break;

2966 case 'p':

2967 if (padding != 0)

2969 else

2971 break;

2972

2973 case 'P':

2975 {

2977

2978

2979

2980

2981

2982 if (leader == NULL || leader->pid == MyProcPid)

2984 padding > 0 ? padding : -padding);

2985 else if (padding != 0)

2987 else

2989 }

2990 else if (padding != 0)

2992 padding > 0 ? padding : -padding);

2993 break;

2994

2995 case 'l':

2996 if (padding != 0)

2998 else

3000 break;

3001 case 'm':

3002

3005

3006 if (padding != 0)

3008 else

3010 break;

3011 case 't':

3012 {

3014 char strfbuf[128];

3015

3017 "%Y-%m-%d %H:%M:%S %Z",

3019 if (padding != 0)

3021 else

3023 }

3024 break;

3025 case 'n':

3026 {

3027 char strfbuf[128];

3028

3030 {

3033 }

3034

3035 snprintf(strfbuf, sizeof(strfbuf), "%ld.%03d",

3038

3039 if (padding != 0)

3041 else

3043 }

3044 break;

3045 case 's':

3046 {

3048

3049 if (padding != 0)

3051 else

3053 }

3054 break;

3055 case 'i':

3057 {

3058 const char *psdisp;

3059 int displen;

3060

3062 if (padding != 0)

3064 else

3066 }

3067 else if (padding != 0)

3069 padding > 0 ? padding : -padding);

3070 break;

3071 case 'L':

3072 {

3073 const char *local_host;

3074

3076 {

3078 {

3079

3080

3081

3082

3087 NULL, 0,

3088 NI_NUMERICHOST | NI_NUMERICSERV);

3089 }

3091 }

3092 else

3093 {

3094

3095 local_host = "[none]";

3096 }

3097 if (padding != 0)

3099 else

3101 }

3102 break;

3103 case 'r':

3105 {

3106 if (padding != 0)

3107 {

3109 {

3110

3111

3112

3113

3114

3115

3116

3117

3118 char *hostport;

3119

3122 pfree(hostport);

3123 }

3124 else

3126 }

3127 else

3128 {

3129

3135 }

3136 }

3137 else if (padding != 0)

3139 padding > 0 ? padding : -padding);

3140 break;

3141 case 'h':

3143 {

3144 if (padding != 0)

3146 else

3148 }

3149 else if (padding != 0)

3151 padding > 0 ? padding : -padding);

3152 break;

3153 case 'q':

3154

3155

3157 return;

3158 break;

3159 case 'v':

3160

3162 {

3163 if (padding != 0)

3164 {

3165 char strfbuf[128];

3166

3167 snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u",

3170 }

3171 else

3173 }

3174 else if (padding != 0)

3176 padding > 0 ? padding : -padding);

3177 break;

3178 case 'x':

3179 if (padding != 0)

3181 else

3183 break;

3184 case 'e':

3185 if (padding != 0)

3187 else

3189 break;

3190 case 'Q':

3191 if (padding != 0)

3194 else

3197 break;

3198 default:

3199

3200 break;

3201 }

3202 }

3203}

3204

3205

3206

3207

3208

3209char *

3211{

3212 static char buf[12];

3213 int i;

3214

3215 for (i = 0; i < 5; i++)

3216 {

3218 sql_state >>= 6;

3219 }

3220

3221 buf[i] = '\0';

3222 return buf;

3223}

3224

3225

3226

3227

3228

3229static void

3231{

3233 bool fallback_to_stderr = false;

3234

3236

3239

3242

3245 else

3247

3254

3256

3258 {

3260 {

3265 }

3266 else if (edata->detail)

3267 {

3272 }

3273 if (edata->hint)

3274 {

3279 }

3281 {

3286 }

3288 {

3293 }

3295 {

3296

3298 {

3303 }

3305 {

3309 }

3310 }

3312 {

3317 }

3318 }

3319

3320

3321

3322

3324 {

3329 }

3330

3331#ifdef HAVE_SYSLOG

3332

3334 {

3335 int syslog_level;

3336

3337 switch (edata->elevel)

3338 {

3344 syslog_level = LOG_DEBUG;

3345 break;

3346 case LOG:

3349 syslog_level = LOG_INFO;

3350 break;

3354 syslog_level = LOG_NOTICE;

3355 break;

3357 syslog_level = LOG_WARNING;

3358 break;

3360 syslog_level = LOG_ERR;

3361 break;

3363 default:

3364 syslog_level = LOG_CRIT;

3365 break;

3366 }

3367

3368 write_syslog(syslog_level, buf.data);

3369 }

3370#endif

3371

3372#ifdef WIN32

3373

3375 {

3376 write_eventlog(edata->elevel, buf.data, buf.len);

3377 }

3378#endif

3379

3380

3382 {

3383

3384

3385

3386

3387

3390 else

3391 fallback_to_stderr = true;

3392 }

3393

3394

3396 {

3397

3398

3399

3400

3401

3403 {

3405 }

3406 else

3407 fallback_to_stderr = true;

3408 }

3409

3410

3411

3412

3413

3416 fallback_to_stderr)

3417 {

3418

3419

3420

3421

3422

3425#ifdef WIN32

3426

3427

3428

3429

3430

3431

3432

3433

3435 write_eventlog(edata->elevel, buf.data, buf.len);

3436#endif

3437 else

3439 }

3440

3441

3444

3445

3447}

3448

3449

3450

3451

3452

3453

3454

3455

3456

3457

3458

3459

3460

3461

3462

3463

3464

3465

3466

3467

3468

3469void

3471{

3473 int fd = fileno(stderr);

3474 int rc;

3475

3477

3487

3488

3490 {

3491

3495 (void) rc;

3498 }

3499

3500

3505 (void) rc;

3506}

3507

3508

3509

3510

3511

3512

3513

3514

3515

3516

3517

3518

3519

3520static void

3522{

3525 else

3527}

3528

3529

3530

3531

3532static void

3534{

3536

3537

3538

3539

3540

3541

3542

3543

3545 {

3546

3547 const char *sev;

3548 char tbuf[12];

3549

3550

3553 else

3555

3561

3564

3565

3569 else

3571

3573 {

3576 }

3577

3578

3579

3580 if (edata->hint)

3581 {

3584 }

3585

3587 {

3590 }

3591

3593 {

3596 }

3597

3599 {

3602 }

3603

3605 {

3608 }

3609

3611 {

3614 }

3615

3617 {

3620 }

3621

3623 {

3627 }

3628

3630 {

3634 }

3635

3637 {

3640 }

3641

3643 {

3646 }

3647

3648 if (edata->lineno > 0)

3649 {

3653 }

3654

3656 {

3659 }

3660

3661 pq_sendbyte(&msgbuf, '\0');

3662

3664 }

3665 else

3666 {

3667

3669

3671

3673

3676 else

3678

3680

3681

3683

3685 }

3686

3687

3688

3689

3690

3691

3692

3693

3694

3696}

3697

3698

3699

3700

3701

3702

3703

3704

3705

3706

3707

3708

3709

3710const char *

3712{

3713 const char *prefix;

3714

3715 switch (elevel)

3716 {

3723 break;

3724 case LOG:

3727 break;

3730 break;

3733 break;

3737 break;

3740 break;

3743 break;

3746 break;

3747 default:

3748 prefix = "???";

3749 break;

3750 }

3751

3752 return prefix;

3753}

3754

3755

3756

3757

3758

3759

3760

3761

3762static void

3764{

3765 char ch;

3766

3767 while ((ch = *str++) != '\0')

3768 {

3770 if (ch == '\n')

3772 }

3773}

3774

3775

3776

3777

3778

3779

3780

3781void

3783{

3784 va_list ap;

3785

3786#ifdef WIN32

3787 char errbuf[2048];

3788#endif

3789

3790 fmt = _(fmt);

3791

3792 va_start(ap, fmt);

3793#ifndef WIN32

3794

3796 fflush(stderr);

3797#else

3798 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);

3799

3800

3801

3802

3803

3805 {

3806 write_eventlog(ERROR, errbuf, strlen(errbuf));

3807 }

3808 else

3809 {

3810

3812 fflush(stderr);

3813 }

3814#endif

3815 va_end(ap);

3816}

void ExceptionalCondition(const char *conditionName, const char *fileName, int lineNumber)

uint64 pgstat_get_my_query_id(void)

#define pg_attribute_format_arg(a)

#define pg_attribute_cold

#define PG_TEXTDOMAIN(domain)

#define MemSet(start, val, len)

void write_csvlog(ErrorData *edata)

void assign_syslog_facility(int newval, void *extra)

int getinternalerrposition(void)

static bool should_output_to_client(int elevel)

void assign_syslog_ident(const char *newval, void *extra)

int errcode_for_socket_access(void)

bool errsave_start(struct Node *context, const char *domain)

static void log_line_prefix(StringInfo buf, ErrorData *edata)

static const char * process_log_prefix_padding(const char *p, int *ppadding)

int err_generic_string(int field, const char *str)

int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

void errsave_finish(struct Node *context, const char *filename, int lineno, const char *funcname)

static char formatted_log_time[FORMATTED_TS_LEN]

int internalerrquery(const char *query)

static char formatted_start_time[FORMATTED_TS_LEN]

int internalerrposition(int cursorpos)

static void send_message_to_frontend(ErrorData *edata)

bool check_log_of_query(ErrorData *edata)

int errmsg_internal(const char *fmt,...)

static void append_with_tabs(StringInfo buf, const char *str)

char * format_elog_string(const char *fmt,...)

int errhidestmt(bool hide_stmt)

bool errstart(int elevel, const char *domain)

void EmitErrorReport(void)

bool syslog_split_messages

static void FreeErrorDataContents(ErrorData *edata)

static int errordata_stack_depth

char * GetErrorContextStack(void)

static void err_sendstring(StringInfo buf, const char *str)

void FreeErrorData(ErrorData *edata)

void assign_backtrace_functions(const char *newval, void *extra)

const char * error_severity(int elevel)

static ErrorData * get_error_stack_entry(void)

int errdetail_internal(const char *fmt,...)

static bool saved_timeval_set

int errcode_for_file_access(void)

static char * backtrace_function_list

int errdetail(const char *fmt,...)

int errcontext_msg(const char *fmt,...)

static int save_format_errnumber

bool check_backtrace_functions(char **newval, void **extra, GucSource source)

void pre_format_elog_string(int errnumber, const char *domain)

static int recursion_depth

ErrorContextCallback * error_context_stack

int errhint_internal(const char *fmt,...)

static struct timeval saved_timeval

void ReThrowError(ErrorData *edata)

static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str)

char * get_formatted_start_time(void)

static bool matches_backtrace_functions(const char *funcname)

ErrorData * CopyErrorData(void)

bool check_log_destination(char **newval, void **extra, GucSource source)

void FlushErrorState(void)

int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

int errhint(const char *fmt,...)

static bool is_log_level_output(int elevel, int log_min_level)

void ThrowErrorData(ErrorData *edata)

bool message_level_is_interesting(int elevel)

void write_pipe_chunks(char *data, int len, int dest)

int errhidecontext(bool hide_ctx)

emit_log_hook_type emit_log_hook

bool syslog_sequence_numbers

static void send_message_to_server_log(ErrorData *edata)

char * Log_destination_string

static void write_console(const char *line, int len)

#define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit)

static void set_stack_entry_location(ErrorData *edata, const char *filename, int lineno, const char *funcname)

pg_attribute_cold bool errstart_cold(int elevel, const char *domain)

#define CHECK_STACK_DEPTH()

static void set_stack_entry_domain(ErrorData *edata, const char *domain)

#define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval)

static bool should_output_to_server(int elevel)

const char * get_backend_type_for_log(void)

int errcode(int sqlerrcode)

int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

void write_stderr(const char *fmt,...)

int errmsg(const char *fmt,...)

void log_status_format(StringInfo buf, const char *format, ErrorData *edata)

char * get_formatted_log_time(void)

bool in_error_recursion_trouble(void)

void errfinish(const char *filename, int lineno, const char *funcname)

static const char * err_gettext(const char *str) pg_attribute_format_arg(1)

int errposition(int cursorpos)

#define ERRORDATA_STACK_SIZE

int errhint_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

int errdetail_log(const char *fmt,...)

char * unpack_sql_state(int sql_state)

static pg_noinline void set_backtrace(ErrorData *edata, int num_skip)

int set_errcontext_domain(const char *domain)

void reset_formatted_start_time(void)

static ErrorData errordata[ERRORDATA_STACK_SIZE]

sigjmp_buf * PG_exception_stack

static const char * save_format_domain

void assign_log_destination(const char *newval, void *extra)

void(* emit_log_hook_type)(ErrorData *edata)

#define WARNING_CLIENT_ONLY

#define LOG_DESTINATION_JSONLOG

#define LOG_DESTINATION_SYSLOG

#define LOG_DESTINATION_STDERR

#define ereport(elevel,...)

#define LOG_DESTINATION_EVENTLOG

#define LOG_DESTINATION_CSVLOG

#define palloc_object(type)

volatile uint32 QueryCancelHoldoffCount

ProtocolVersion FrontendProtocol

volatile uint32 InterruptHoldoffCount

volatile uint32 CritSectionCount

char OutputFileName[MAXPGPATH]

void * guc_malloc(int elevel, size_t size)

#define GUC_check_errdetail

int log_min_error_statement

static int syslog_facility

char * backtrace_functions

Assert(PointerIsAligned(start, uint64))

int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)

bool proc_exit_inprogress

void write_jsonlog(ErrorData *edata)

void list_free(List *list)

int pg_mbcliplen(const char *mbstr, int len, int limit)

int GetMessageEncoding(void)

char * MemoryContextStrdup(MemoryContext context, const char *string)

void MemoryContextReset(MemoryContext context)

char * pstrdup(const char *in)

void pfree(void *pointer)

MemoryContext CurrentMemoryContext

MemoryContext ErrorContext

#define CHECK_FOR_INTERRUPTS()

const char * GetBackendTypeDesc(BackendType backendType)

BackendType MyBackendType

#define IsA(nodeptr, _type_)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

#define DEFAULT_EVENT_SOURCE

static rewind_source * source

SessionEndType pgStatSessionEndCause

size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)

struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)

PGDLLIMPORT pg_tz * log_timezone

#define ALL_CONNECTION_FAILURE_ERRNOS

int pg_strcasecmp(const char *s1, const char *s2)

CommandDest whereToSendOutput

const char * debug_query_string

#define PG_DIAG_INTERNAL_QUERY

#define PG_DIAG_SCHEMA_NAME

#define PG_DIAG_CONSTRAINT_NAME

#define PG_DIAG_DATATYPE_NAME

#define PG_DIAG_SOURCE_LINE

#define PG_DIAG_STATEMENT_POSITION

#define PG_DIAG_SOURCE_FILE

#define PG_DIAG_MESSAGE_HINT

#define PG_DIAG_SEVERITY_NONLOCALIZED

#define PG_DIAG_TABLE_NAME

#define PG_DIAG_MESSAGE_PRIMARY

#define PG_DIAG_COLUMN_NAME

#define PG_DIAG_MESSAGE_DETAIL

#define PG_DIAG_SOURCE_FUNCTION

#define PG_DIAG_INTERNAL_POSITION

bool ClientAuthInProgress

BackgroundWorker * MyBgworkerEntry

int pq_putmessage_v2(char msgtype, const char *s, size_t len)

#define PG_PROTOCOL_MAJOR(v)

void pq_sendstring(StringInfo buf, const char *str)

void pq_endmessage(StringInfo buf)

void pq_beginmessage(StringInfo buf, char msgtype)

void pq_send_ascii_string(StringInfo buf, const char *str)

static void pq_sendbyte(StringInfo buf, uint8 byt)

static int fd(const char *x, int i)

#define INVALID_PROC_NUMBER

#define PqMsg_ErrorResponse

#define PqMsg_NoticeResponse

const char * get_ps_display(int *displen)

char * psprintf(const char *fmt,...)

void appendStringInfo(StringInfo str, const char *fmt,...)

void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)

void appendStringInfoSpaces(StringInfo str, int count)

void appendStringInfoString(StringInfo str, const char *s)

void appendStringInfoChar(StringInfo str, char ch)

void initStringInfo(StringInfo str)

#define appendStringInfoCharMacro(str, ch)

char bgw_type[BGW_MAXLEN]

struct ErrorContextCallback * previous

void(* callback)(void *arg)

struct MemoryContextData * assoc_context

const char * context_domain

struct sockaddr_storage addr

void write_syslogger_file(const char *buffer, int count, int destination)

#define PIPE_PROTO_DEST_JSONLOG

#define PIPE_PROTO_IS_LAST

#define PIPE_PROTO_DEST_CSVLOG

#define PIPE_PROTO_DEST_STDERR

bool SplitIdentifierString(char *rawstring, char separator, List **namelist)

int pgwin32_is_service(void)

int gettimeofday(struct timeval *tp, void *tzp)

TransactionId GetTopTransactionIdIfAny(void)