Thread
Commits
-
ecpg: clean up some other assorted memory leaks.
- 2b41de4a5b42 18.0 landed
-
ecpg: fix some memory leakage of data-type-related structures.
- 0e6060790d65 18.0 landed
-
ecpg: put all string-valued tokens returned by pgc.l in local storage.
- 85312d95e959 18.0 landed
-
ecpg: fix more minor mishandling of bad input in preprocessor.
- 1fed234f9faf 18.0 landed
-
ecpg: fix some minor mishandling of bad input in preprocessor.
- 9b4bf5169064 18.0 landed
-
ecpg: avoid breaking the IDENT precedence level in two.
- 9812138593f3 18.0 landed
-
ecpg: improve preprocessor's memory management.
- 1acd0f55274f 18.0 landed
-
ecpg: move some functions into a new file ecpg/preproc/util.c.
- f18231e81759 18.0 landed
-
ecpg: re-implement preprocessor's string management.
- a542d5614bdb 18.0 landed
-
ecpg: major cleanup, simplification, and documentation of parse.pl.
- 6b0054994475 18.0 landed
-
ecpg: remove check_rules.pl.
- 293fd24425b5 18.0 landed
-
ecpg: clean up documentation of parse.pl, and add more input checking.
- 00b0e7204d53 18.0 landed
-
Clean up indentation and whitespace inconsistencies in ecpg.
- 97add39c038b 18.0 landed
-
Exclude flex-generated code from coverage testing
- 421167362242 11.0 cited
-
ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-04-19T02:18:34Z
Here is a patch series that aims to clean up ecpg's preprocessor code a little and fix the compile time problems we're seeing with late-model clang [1]. I guess whether it's a cleanup is in the eye of the beholder, but it definitely succeeds at fixing compile time: for me, the time needed to compile preproc.o with clang 16 drops from 104 seconds to less than 1 second. It might be a little faster at processing input too, though that wasn't the primary goal. The reason that clang is having a problem seems to be the large number of virtually-duplicate semantic actions in the generated preproc.y. So I looked for a way to allow most productions to use the default semantic action rather than having to write anything. The core idea of this patch is to stop returning <str> results from grammar nonterminals and instead pass the strings back as Bison location data, which we can do by redefining YYLTYPE as "char *". Since ecpg isn't using Bison's location logic for error reports, and seems unlikely to do so in future, this doesn't cost us anything. Then we can implement a one-size-fits-most token concatenation rule in YYLLOC_DEFAULT, and only the various handmade rules that don't want to just concatenate their inputs need to do something different. (Within those handmade rules, the main notational change needed is to write "@N" not "$N" for the string value of the N'th input token, and "@@" not "$@" for the output string value.) Aside from not giving clang indigestion, this makes the compiled parser a little smaller since there are fewer semantic actions that need code space. As Andres remarked in the other thread, the parse.pl script that constructs preproc.y is undocumented and unreadable, so I spent a good deal of time reverse-engineering and cleaning that up before I went to work on the actual problem. Four of the six patches in this series are in the way of cleanup and adding documentation, with no significant behavioral changes. The patch series comprises: 0001: pgindent the code in pgc.l and preproc.y's precursor files. Yeah, this was my latent OCD rearing its head, but I hate looking at or working on messy code. It did actually pay some dividends later on, by making it easier to make bulk edits. 0002: improve the external documentation and error checking of parse.pl. This was basically to convince myself that I knew what it was supposed to do before I started changing it. The error checks did find some errors, too: in particular, it turns out there are two unused entries in ecpg.addons. (This implies that check_rules.pl is completely worthless and should be nuked: it adds build cycles and maintenance effort while failing to reliably accomplish its one job of detecting dead rules, because what it is testing is not the same thing that parse.pl actually does. I've not included that removal in this patch series, though.) 0003: clean up and simplify parse.pl, and write some internal documentation for it. The effort of understanding it exposed that there was a pretty fair amount of dead or at least redundant code, so I got rid of that. This patch changes the output preproc.y file only to the extent of removing some blank lines that didn't seem very useful to preserve. 0004: this is where something useful happens, specifically where we change <str>-returning productions to return void and instead pass back the desired output string as location data. In most cases the productions now need no explicit semantic action at all, allowing substantial simplification in parse.pl. 0005: more cleanup. I didn't want to add more memory-management code to preproc/type.c, where mm_alloc and mm_strdup have lived for no explicable reason. I pulled those and a couple of other functions out to a new file util.c, so as to have a better home for new utility code. 0006: the big problem with 0004 is that it can't use the trick of freeing input substrings as soon as it's created the merged string, as cat_str and friends have historically done. That's because YYLLOC_DEFAULT runs before the rule's semantic action if any, so that if the action does need to look at the input strings, they'd already be freed. So 0004 is leaking memory rather badly. Fix that by creating a notion of "local" memory that will be reclaimed at end of statement, analogously to short-lived memory contexts in the backend. All the string concatenation work happens in short-lived storage and we don't worry about getting rid of intermediate values immediately. By making cat_str and friends work similarly, we can get rid of quite a lot of explicit mm_strdup calls, although we do have to add some at places where we're building long-lived data structures. This should greatly reduce the malloc/free traffic too, at the cost of eating somewhat more space intra-statement. In my view 0006 is about the scariest part of this, as it's hard to be sure that there are no use-after-free problems wherein a pointer to a short-lived string survives past end of statement. It gets through the ecpg regression tests under valgrind successfully, but I don't have much faith in the thoroughness of the code coverage of those tests. (If our code coverage tools worked on bison/flex stuff, maybe this'd be less scary ... but they don't.) I'll park this in the July commitfest. regards, tom lane [1] https://www.postgresql.org/message-id/flat/CAGECzQQg4qmGbqqLbK9yyReWd1g%3Dd7T07_gua%2BRKXsdsW9BG-Q%40mail.gmail.com
-
Re: ECPG cleanup and fix for clang compile-time problem
Andres Freund <andres@anarazel.de> — 2024-04-19T03:03:46Z
Hi, On 2024-04-18 22:18:34 -0400, Tom Lane wrote: > Here is a patch series that aims to clean up ecpg's preprocessor > code a little and fix the compile time problems we're seeing with > late-model clang [1]. I guess whether it's a cleanup is in the eye of > the beholder, but it definitely succeeds at fixing compile time: for > me, the time needed to compile preproc.o with clang 16 drops from > 104 seconds to less than 1 second. It might be a little faster at > processing input too, though that wasn't the primary goal. Nice! I'll look at this more later. For now I just wanted to point one minor detail: > (If our code coverage tools worked on bison/flex stuff, > maybe this'd be less scary ... but they don't.) For bison coverage seems to work, see e.g.: https://coverage.postgresql.org/src/interfaces/ecpg/preproc/preproc.y.gcov.html#10638 I think the only reason it doesn't work for flex is that we have /* LCOV_EXCL_START */ /* LCOV_EXCL_STOP */ around the scanner "body". Without that I get reasonable-looking, albeit not very comforting, coverage for pgc.l as well. |Lines |Functions|Branches Filename |Rate Num|Rate Num|Rate Num src/interfaces/ecpg/preproc/pgc.l |65.9% 748|87.5% 8| - 0 src/interfaces/ecpg/preproc/preproc.y |29.9% 4964|66.7% 15| - 0 This has been introduced by commit 421167362242ce1fb46d6d720798787e7cd65aad Author: Peter Eisentraut <peter_e@gmx.net> Date: 2017-08-10 23:33:47 -0400 Exclude flex-generated code from coverage testing Flex generates a lot of functions that are not actually used. In order to avoid coverage figures being ruined by that, mark up the part of the .l files where the generated code appears by lcov exclusion markers. That way, lcov will typically only reported on coverage for the .l file, which is under our control, but not for the .c file. Reviewed-by: Michael Paquier <michael.paquier@gmail.com> but I don't think it's working as intended, as it's also preventing coverage for the actual scanner definition. Greetings, Andres Freund -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-04-19T03:11:52Z
Andres Freund <andres@anarazel.de> writes: > On 2024-04-18 22:18:34 -0400, Tom Lane wrote: >> (If our code coverage tools worked on bison/flex stuff, >> maybe this'd be less scary ... but they don't.) > For bison coverage seems to work, see e.g.: Yeah, I'd just noticed that --- I had it in my head that we'd put LCOV_EXCL_START/STOP into bison files too, but nope they are only in flex files. That's good for this specific problem, because the code I'm worried about is all in the bison file. > around the scanner "body". Without that I get reasonable-looking, albeit not > very comforting, coverage for pgc.l as well. I was just looking locally at what I got by removing that, and sadly I don't think I believe it: there are a lot of places where it claims we hit lines we don't, and vice versa. That might be partially blamable on old tools on my RHEL8 workstation, but it sure seems that flex output confuses lcov to some extent. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Andres Freund <andres@anarazel.de> — 2024-04-19T03:40:22Z
On 2024-04-18 23:11:52 -0400, Tom Lane wrote: > Andres Freund <andres@anarazel.de> writes: > > On 2024-04-18 22:18:34 -0400, Tom Lane wrote: > >> (If our code coverage tools worked on bison/flex stuff, > >> maybe this'd be less scary ... but they don't.) > > > For bison coverage seems to work, see e.g.: > > Yeah, I'd just noticed that --- I had it in my head that we'd put > LCOV_EXCL_START/STOP into bison files too, but nope they are only > in flex files. That's good for this specific problem, because the > code I'm worried about is all in the bison file. At least locally the coverage seems to make sense too, both for the main grammar and for ecpg's. > > around the scanner "body". Without that I get reasonable-looking, albeit not > > very comforting, coverage for pgc.l as well. > > I was just looking locally at what I got by removing that, and sadly > I don't think I believe it: there are a lot of places where it claims > we hit lines we don't, and vice versa. That might be partially > blamable on old tools on my RHEL8 workstation, but it sure seems > that flex output confuses lcov to some extent. Hm. Here it mostly looks reasonable, except that at least things seem off by 1. And sure enough, if I look at pgc.l it has code like case 2: YY_RULE_SETUP #line 465 "/home/andres/src/postgresql/src/interfaces/ecpg/preproc/pgc.l" { token_start = yytext; state_before_str_start = YYSTATE; However line 465 is actually the "token_start" line. Further down this seems to get worse, by "<<EOF>>" it's off by 4 lines. $ apt policy flex flex: Installed: 2.6.4-8.2+b2 Candidate: 2.6.4-8.2+b2 Version table: *** 2.6.4-8.2+b2 500 500 http://mirrors.ocf.berkeley.edu/debian unstable/main amd64 Packages 100 /var/lib/dpkg/status Greetings, Andres Freund -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-04-19T03:53:59Z
Andres Freund <andres@anarazel.de> writes: > On 2024-04-18 23:11:52 -0400, Tom Lane wrote: >> I was just looking locally at what I got by removing that, and sadly >> I don't think I believe it: there are a lot of places where it claims >> we hit lines we don't, and vice versa. That might be partially >> blamable on old tools on my RHEL8 workstation, but it sure seems >> that flex output confuses lcov to some extent. > Hm. Here it mostly looks reasonable, except that at least things seem off by > 1. Yeah, now that you mention it what I'm seeing looks like the line numbering might be off-by-one. Time for a bug report? regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-04-19T15:21:05Z
One other bit of randomness that I noticed: ecpg's parse.pl has this undocumented bit of logic: if ($a eq 'IDENT' && $prior eq '%nonassoc') { # add more tokens to the list $str = $str . "\n%nonassoc CSTRING"; } The net effect of that is that, where gram.y writes %nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */ %nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH %left Op OPERATOR /* multi-character ops and user-defined operators */ preproc.c has %nonassoc UNBOUNDED NESTED %nonassoc IDENT %nonassoc CSTRING PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH %left Op OPERATOR If you don't find that scary as heck, I suggest reading the very long comment just in front of the cited lines of gram.y. The argument why assigning these keywords a precedence at all is OK depends heavily on it being the same precedence as IDENT, yet here's ECPG randomly breaking that. We seem to have avoided problems though, because if I fix things by manually editing preproc.y to re-join the lines: %nonassoc IDENT CSTRING PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP the generated preproc.c doesn't change at all. Actually, I can take CSTRING out of this list altogether and it still doesn't change the results ... although looking at how CSTRING is used, it looks safer to give it the same precedence as IDENT. I think we should change parse.pl to give one or the other of these results before something more serious breaks there. regards, tom lane -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-07-05T15:56:55Z
The cfbot noticed that this patchset had a conflict with d35cd0619, so here's a rebase. It's just a rebase of v1, no other changes. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
John Naylor <johncnaylorls@gmail.com> — 2024-08-12T05:33:49Z
On Fri, Apr 19, 2024 at 10:21 PM Tom Lane <tgl@sss.pgh.pa.us> wrote: > > One other bit of randomness that I noticed: ecpg's parse.pl has > this undocumented bit of logic: > > if ($a eq 'IDENT' && $prior eq '%nonassoc') > { > > # add more tokens to the list > $str = $str . "\n%nonassoc CSTRING"; > } > preproc.c has > > %nonassoc UNBOUNDED NESTED > %nonassoc IDENT > %nonassoc CSTRING PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP > SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH > %left Op OPERATOR > > If you don't find that scary as heck, I suggest reading the very long > comment just in front of the cited lines of gram.y. The argument why > assigning these keywords a precedence at all is OK depends heavily > on it being the same precedence as IDENT, yet here's ECPG randomly > breaking that. Before 7f380c59f (Reduce size of backend scanner's tables), it was even more spread out: # add two more tokens to the list $str = $str . "\n%nonassoc CSTRING\n%nonassoc UIDENT"; ...giving: %nonassoc UNBOUNDED %nonassoc IDENT %nonassoc CSTRING %nonassoc UIDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP > We seem to have avoided problems though, because if I fix things > by manually editing preproc.y to re-join the lines: > > %nonassoc IDENT CSTRING PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP > > the generated preproc.c doesn't change at all. On a whim I tried rejoining on v12 and the .c doesn't change there, either. > Actually, I can > take CSTRING out of this list altogether and it still doesn't > change the results ... although looking at how CSTRING is used, > it looks safer to give it the same precedence as IDENT. Doing that on v12 on top of rejoining results in a shift-reduce conflict, so I imagine that's why it's there. Maybe it's outdated, but this backs up your inclination that it's safer to keep. -
Re: ECPG cleanup and fix for clang compile-time problem
John Naylor <johncnaylorls@gmail.com> — 2024-08-12T10:46:22Z
On Fri, Jul 5, 2024 at 10:59 PM Tom Lane <tgl@sss.pgh.pa.us> wrote: > > The cfbot noticed that this patchset had a conflict with d35cd0619, > so here's a rebase. It's just a rebase of v1, no other changes. Hi Tom, I started looking at the earlier cleanup patches. 0001 seems straightforward. Note: It doesn't apply cleanly anymore, but does with 'patch'. 0002 LGTM, just a couple minor comments: --- a/src/interfaces/ecpg/preproc/parse.pl +++ b/src/interfaces/ecpg/preproc/parse.pl @@ -1,7 +1,13 @@ #!/usr/bin/perl # src/interfaces/ecpg/preproc/parse.pl # parser generator for ecpg version 2 -# call with backend parser as stdin +# +# See README.parser for some explanation of what this does. Doesn't this patch set put us up to version 3? ;-) Looking in the history, a very long time ago a separate "parse2.pl" was committed for some reason, but that was reconciled some time later. This patch doesn't need to get rid of that meaningless version number, but I find it distracting. + # There may be multiple ECPG: lines and then multiple lines of code. + # Each block of code needs to be added to all prior ECPG records. This took me a while to parse at first. Some places in this script put quotes around words-with-colons, and that seems good for readability. 0003: Looks a heck of a lot better, but I didn't try to understand everything in the script, either before or after. + # Emit the target part of the rule. + # Note: the leading space is just to match + # the old, rather weird output logic. + $tstr = ' ' . $non_term_id . ':'; + add_to_buffer('rules', $tstr); Removing the leading space (or making it two spaces) has no effect on the output -- does that get normalized elsewhere? That's all I have for now. -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-08-12T19:19:57Z
John Naylor <johncnaylorls@gmail.com> writes: > I started looking at the earlier cleanup patches. Thanks for looking! > 0001 seems straightforward. Note: It doesn't apply cleanly anymore, > but does with 'patch'. Odd, after rebasing it seems to have only line-number differences. > + # Emit the target part of the rule. > + # Note: the leading space is just to match > + # the old, rather weird output logic. > + $tstr = ' ' . $non_term_id . ':'; > + add_to_buffer('rules', $tstr); > Removing the leading space (or making it two spaces) has no effect on > the output -- does that get normalized elsewhere? It does affect horizontal space in the generated preproc.y file, which'd have no effect on the derived preproc.c file. I tweaked the commit message to clarify that. I adopted your other suggestions, no need to rehash them. Here's a rebased but otherwise identical patchset. I also added an 0007 that removes check_rules.pl as threatened. regards, tom lane -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-08-15T00:43:36Z
I wrote: > Here's a rebased but otherwise identical patchset. I also added > an 0007 that removes check_rules.pl as threatened. I've done some more work on this and hope to post an updated patchset tomorrow. Before that though, is there any objection to going ahead with pushing the 0001 patch (pgindent'ing ecpg's lexer and parser files)? It's pretty bulky yet of no intellectual interest, so I'd like to stop carrying it forward. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Peter Eisentraut <peter@eisentraut.org> — 2024-08-15T07:20:13Z
On 15.08.24 02:43, Tom Lane wrote: > I wrote: >> Here's a rebased but otherwise identical patchset. I also added >> an 0007 that removes check_rules.pl as threatened. > > I've done some more work on this and hope to post an updated patchset > tomorrow. Before that though, is there any objection to going ahead > with pushing the 0001 patch (pgindent'ing ecpg's lexer and parser > files)? It's pretty bulky yet of no intellectual interest, so I'd > like to stop carrying it forward. The indentation patch looks good to me and it would be good to get it out of the way.
-
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-08-15T19:58:35Z
Peter Eisentraut <peter@eisentraut.org> writes: > On 15.08.24 02:43, Tom Lane wrote: >> I've done some more work on this and hope to post an updated patchset >> tomorrow. Before that though, is there any objection to going ahead >> with pushing the 0001 patch (pgindent'ing ecpg's lexer and parser >> files)? It's pretty bulky yet of no intellectual interest, so I'd >> like to stop carrying it forward. > The indentation patch looks good to me and it would be good to get it > out of the way. Thanks, done. Here's a revised patchset. 0001-0003 are substantially identical to the previous 0002-0004. Likewise 0005 is basically the same as previous 0006, and 0009 is identical to the previous 0007. 0004 differs from the previous 0005 in also moving the cat_str/make_str functions into util.c, because I found that at least the make_str functions could be useful in pgc.l. The new stuff is in 0006-0008, and what it basically does is clean up all remaining memory leakage in ecpg --- or at least, all that valgrind can find while running ecpg's regression tests. (I'm not fool enough to think that there might not be some in unexercised code paths.) It's fairly straightforward attention to detail in data structure management. I discovered the need for more effort on memory leakage by doing some simple performance testing (basically, running ecpg on a big file made by pasting together lots of copies of some of the regression test inputs). v3 was slower and consumed more memory than HEAD :-(. HEAD does already leak quite a bit of memory, but v3 was worse, mainly because the string tokens returned by pgc.l weren't being reclaimed. I hadn't really set out to drive the leakage to zero, but it turned out to not be that hard, so I did it. With those fixes, I see v4 running maybe 10% faster than HEAD, rather than a similar amount slower. I'm content with that result, and feel that this may now be commit-quality. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-08-15T20:21:42Z
I wrote: > Thanks, done. Here's a revised patchset. The cfbot points out that I should probably have marked progname as "static" in 0008. I'm not going to repost the patchset just for that, though. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-10-04T20:46:44Z
I wrote: > The cfbot points out that I should probably have marked progname > as "static" in 0008. I'm not going to repost the patchset just for > that, though. Rebase needed after f22e84df1, so here's an update that rebases up to HEAD and adds the missing "static". No other changes. (Anybody want to review this? I'm getting tired of rebasing it, and we're missing out on the clang build time savings.) regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
John Naylor <johncnaylorls@gmail.com> — 2024-10-07T09:52:04Z
On Saturday, October 5, 2024, Tom Lane <tgl@sss.pgh.pa.us> wrote: > > > Rebase needed after f22e84df1, so here's an update that rebases > up to HEAD and adds the missing "static". No other changes. > > (Anybody want to review this? I'm getting tired of rebasing it, > and we're missing out on the clang build time savings.) Sorry for the delay, I'll respond in a couple days.
-
Re: ECPG cleanup and fix for clang compile-time problem
John Naylor <johncnaylorls@gmail.com> — 2024-10-11T11:43:22Z
> [v5] 0001 - LGTM, maybe can be squashed with 0009? 0002 - I went through this again and don't see anything that should raise eyebrows. + # HACK: insert our own %nonassoc line after IDENT. + # XXX: this seems pretty wrong, IDENT is not last on its line! We can come back to this afterwards, as mentioned elsewhere in the thread. 0003 Clang is what motivated this, but gcc also shows a speedup -- from 5.9s to 1.6s on this old machine, which is great. The giant switch statement in preproc.c has about 1/10 the labels as before. +In the original implementation of ecpg, the strings constructed +by grammar rules were returned as the Bison result of each rule. +This led to a large number of effectively-identical rule actions, +which caused compilation-time problems with some versions of clang. +Now, rules that need to return a string are declared as having "Original" is going to be a mystery in a few years -- I'd describe this in terms of "as of PG18" or some such. + * is producing uniformly-cased output of keywords. (That's mostly + * cosmetic, but there are places in ecpglib that expect to receive + * downcased keywords, plus it keeps us regression-test-compatible + * with the old implementation of ecpg.) Ditto with "old". + /* List a token here if pgc.l assigns to base_yylval.str for it */ Does pgc.l need to have a similar comment? 0004 seems like a sensible reorg. 0005 - I wondered if the change of YYLTYPE to "const char *" can be done in a separate commit to make the other changes more legible, but that might not be worth the effort. + * "Local" (or "location"?) memory management support "Local" seems to fit well enough. Tying the arena to the statement level seems sound. I haven't looked closely at 0006 through 0009. One possible concern is that the regression tests might not cover very well, but if you can get valgrind silent for memory leaks for what they do cover, that's certainly a good step.
-
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-10-14T18:25:10Z
John Naylor <johncnaylorls@gmail.com> writes: >> [v5] Thanks for reviewing! I pushed 0001-0005 and 0009, adopting your suggestions except for > + /* List a token here if pgc.l assigns to base_yylval.str for it */ > Does pgc.l need to have a similar comment? That's not a bad suggestion, but I couldn't see any very useful place to put such a comment. > I haven't looked closely at 0006 through 0009. One possible concern is > that the regression tests might not cover very well, but if you can > get valgrind silent for memory leaks for what they do cover, that's > certainly a good step. Attached are rebased and renumbered 0006-0008, mostly to keep the cfbot happy. We could actually stop here, if we were feeling lazy, but now that I've done the work I'm inclined to push forward with the rest. The rest is just memory leak removal, and I suspect that nobody really cares that much about small leakage in the preprocessor: you'd have to be running some darn big files through it to notice. FTR, here are the total leaks reported by valgrind for running the ecpg regression tests, using code like $ grep lost: *log | tr -d ',' | awk '{sum += $5} END {print sum}' Before these patches: 25743 after 0003: 59049363 after 0005: 141556 (this is master now) after 0006(0001): 132633 after 0007(0002): 9087 after 0008(0003): 0 So clearly, 0003 by itself wasn't good enough, but arguably no real users will notice the extra inefficiency as of HEAD. Still, I'd kind of like to get 0007 (now 0002) in there, and I believe 0006 (0001) is a necessary prerequisite to that. regards, tom lane -
Re: ECPG cleanup and fix for clang compile-time problem
Alexander Law <exclusion@gmail.com> — 2024-10-16T03:00:00Z
Hello Tom, 14.10.2024 21:25, Tom Lane wrote: > Attached are rebased and renumbered 0006-0008, mostly to keep the > cfbot happy. We could actually stop here, if we were feeling lazy, > but now that I've done the work I'm inclined to push forward with > the rest. > > The rest is just memory leak removal, and I suspect that nobody really > cares that much about small leakage in the preprocessor: you'd have to > be running some darn big files through it to notice. FTR, here are > the total leaks reported by valgrind for running the ecpg regression > tests, using code like Maybe you would like to fix in passing several (not new) defects, I've found while playing with ecpg under Valgrind: echo " EXEC SQL DECLARE cur1 CURSOR FOR stmt1; " > t.pgc valgrind .../preproc/ecpg ... t.pgc ==831888== Conditional jump or move depends on uninitialised value(s) ==831888== at 0x10C7B0: main (ecpg.c:490) ==831888== char_array.pgc:2: WARNING: cursor "cur1" has been declared but not opened Another case: EXEC SQL DECLARE cur_1 CURSOR FOR stmt_1; EXEC SQL FETCH cur_1 INTO :f1[[i]; ==1335775== ==1335775== Conditional jump or move depends on uninitialised value(s) ==1335775== at 0x121294: find_variable (variable.c:211) ==1335775== by 0x11D661: base_yyparse (preproc.y:9749) ==1335775== by 0x10C78F: main (ecpg.c:483) ==1335775== ==1335775== Conditional jump or move depends on uninitialised value(s) ==1335775== at 0x121299: find_variable (variable.c:211) ==1335775== by 0x11D661: base_yyparse (preproc.y:9749) ==1335775== by 0x10C78F: main (ecpg.c:483) ==1335775== ==1335775== Invalid read of size 1 ==1335775== at 0x12128B: find_variable (variable.c:211) ==1335775== by 0x11D661: base_yyparse (preproc.y:9749) ==1335775== by 0x10C78F: main (ecpg.c:483) ==1335775== Address 0x4e3bc80 is 0 bytes after a block of size 8,208 alloc'd ==1335775== at 0x4848899: malloc (vg_replace_malloc.c:381) ==1335775== by 0x120585: mm_alloc (util.c:87) ==1335775== by 0x12065A: loc_alloc (util.c:151) ==1335775== by 0x120701: loc_strdup (util.c:172) ==1335775== by 0x10D9EC: base_yylex_location (parser.c:261) ==1335775== by 0x10D4A1: filtered_base_yylex (parser.c:75) ==1335775== by 0x114CA4: base_yyparse (preproc.c:39316) ==1335775== by 0x10C78F: main (ecpg.c:483) ==1335775== declare.pgc:2: ERROR: variable "f1" is not declared One more case: EXEC SQL BEGIN DECLARE SECTION; int i; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE C CURSOR FOR SELECT 1; { EXEC SQL FETCH 1 IN C INTO :i; } EXEC SQL MOVE BACKWARD 1 IN C; ==961441== Invalid read of size 1 ==961441== at 0x484FBD7: strcmp (vg_replace_strmem.c:924) ==961441== by 0x11442F: add_additional_variables (preproc.y:470) ==961441== by 0x117DEF: base_yyparse (preproc.y:3548) ==961441== by 0x10C78F: main (ecpg.c:483) ==961441== Address 0x0 is not stack'd, malloc'd or (recently) free'd Best regards, Alexander -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-10-16T16:26:48Z
Alexander Lakhin <exclusion@gmail.com> writes: > Maybe you would like to fix in passing several (not new) defects, I've > found while playing with ecpg under Valgrind: Done. After evaluation I concluded that none of these were worth the trouble to back-patch, but by all means let's fix such things in HEAD. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-10-16T17:54:21Z
I wrote: > Attached are rebased and renumbered 0006-0008, mostly to keep the > cfbot happy. For some reason I thought the stuff I pushed later on Monday didn't interact with these patches, but the cfbot disabused me of that folly. Here's a rebased v7 --- no substantive change. regards, tom lane
-
Re: ECPG cleanup and fix for clang compile-time problem
Alexander Law <exclusion@gmail.com> — 2024-10-17T18:00:00Z
Hello Tom, 16.10.2024 19:26, Tom Lane wrote: > Alexander Lakhin <exclusion@gmail.com> writes: >> Maybe you would like to fix in passing several (not new) defects, I've >> found while playing with ecpg under Valgrind: > Done. After evaluation I concluded that none of these were worth the > trouble to back-patch, but by all means let's fix such things in HEAD. Thank you for fixing these defects! I've spent a day testing ecpg preprocessor and found another couple of bugs: 1) EXEC SQL BEGIN DECLARE SECTION; int i = 1; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE c CURSOR FOR SELECT :i; {;} } EXEC SQL OPEN c; ==1247560== ==1247560== Invalid read of size 4 ==1247560== at 0x121C13: dump_variables (variable.c:462) ==1247560== by 0x10CF75: output_statement (output.c:157) ==1247560== by 0x116B6B: base_yyparse (preproc.y:1233) ==1247560== by 0x10C78F: main (ecpg.c:483) ==1247560== Address 0x4e39bc0 is 16 bytes inside a block of size 32 free'd ==1247560== at 0x484B27F: free (vg_replace_malloc.c:872) ==1247560== by 0x1219AE: remove_variables (variable.c:351) ==1247560== by 0x11899F: base_yyparse (preproc.y:7853) ==1247560== by 0x10C78F: main (ecpg.c:483) ==1247560== Block was alloc'd at ==1247560== at 0x4848899: malloc (vg_replace_malloc.c:381) ==1247560== by 0x120703: mm_alloc (util.c:87) ==1247560== by 0x120C3C: new_variable (variable.c:12) ==1247560== by 0x11C27C: base_yyparse (preproc.y:8984) ==1247560== by 0x10C78F: main (ecpg.c:483) ... --- 2) EXEC SQL BEGIN DECLARE SECTION; char s[100]; EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE cur_1 CURSOR FOR SELECT 1; EXEC SQL FETCH cur_1 INTO :s[0]; ==1247848== Invalid read of size 4 ==1247848== at 0x121388: find_variable (variable.c:238) ==1247848== by 0x11D684: base_yyparse (preproc.y:9751) ==1247848== by 0x10C78F: main (ecpg.c:483) ==1247848== Address 0x0 is not stack'd, malloc'd or (recently) free'd --- Also, processing of .../ecpg/test/sql/include.pgc, containing only: EXEC SQL INCLUDE ../sql; emits merely: input in flex scanner failed I think that's all that can be found here without extra efforts. Best regards, Alexander -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-10-17T19:42:41Z
Alexander Lakhin <exclusion@gmail.com> writes: > I've spent a day testing ecpg preprocessor and found another couple of > bugs: Thanks for the report! The first couple of these seem simple enough to fix, so I've done so. As for > Also, processing of .../ecpg/test/sql/include.pgc, containing only: > EXEC SQL INCLUDE ../sql; > emits merely: > input in flex scanner failed what we have here is an attempt to read a directory. On Linux it seems that fopen() is okay with that but then fread() fails with EISDIR. The fread() occurs in code emitted by flex that is totally failing to produce a useful error report: while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, base_yyin)) == 0 && ferror(base_yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ It looks like YY_FATAL_ERROR can only accept a literal string, so I can see why this isn't including strerror(errno), but still I'd say that this is their poor error reporting not ours. The only thing we could really do about it is fstat the fopen's FD and see if it's a directory, but that would only improve matters for EISDIR not any other error cause. I don't believe we've done that anywhere else we use flex, so I'm not inclined to do it here. > I think that's all that can be found here without extra efforts. Thanks for poking at it! I don't feel a huge need to search out ecpg bugs in advance of field reports, but we might as well fix things we do stumble across. regards, tom lane -
Re: ECPG cleanup and fix for clang compile-time problem
John Naylor <johncnaylorls@gmail.com> — 2024-11-27T07:02:23Z
On Tue, Oct 15, 2024 at 1:25 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > > The rest is just memory leak removal, and I suspect that nobody really > cares that much about small leakage in the preprocessor: you'd have to > be running some darn big files through it to notice. FTR, here are > the total leaks reported by valgrind for running the ecpg regression > tests, using code like > > $ grep lost: *log | tr -d ',' | awk '{sum += $5} > END {print sum}' > > Before these patches: 25743 > after 0003: 59049363 > after 0005: 141556 (this is master now) > after 0006(0001): 132633 > after 0007(0002): 9087 > after 0008(0003): 0 > > So clearly, 0003 by itself wasn't good enough, but arguably no > real users will notice the extra inefficiency as of HEAD. > Still, I'd kind of like to get 0007 (now 0002) in there, and > I believe 0006 (0001) is a necessary prerequisite to that. Hi Tom, I think you can go ahead and commit 0001-0003. For 0003 I do admit being confused why valgrind had a problem with progname... FWIW, I also took a quick eyeball check of the coverage output for preproc.y looking for untested non-error branches that do things that are not covered elsewhere, and I didn't notice any. Some places allocating new connections are not covered, which should be handled by 0003. -- John Naylor Amazon Web Services -
Re: ECPG cleanup and fix for clang compile-time problem
Tom Lane <tgl@sss.pgh.pa.us> — 2024-11-27T17:59:38Z
John Naylor <johncnaylorls@gmail.com> writes: > I think you can go ahead and commit 0001-0003. For 0003 I do admit > being confused why valgrind had a problem with progname... Pushed, thanks for looking at it! As for progname, valgrind was unhappy because the local in main() went out of scope at return, but the malloc block was still there. But this was weird coding anyway: pretty much everywhere else, we store progname in a globally-accessible variable so that it can be used in error messages. I figured making it static was a down payment on someday making ecpg's messages honor that convention. > FWIW, I also took a quick eyeball check of the coverage output for > preproc.y looking for untested non-error branches that do things that > are not covered elsewhere, and I didn't notice any. Some places > allocating new connections are not covered, which should be handled by > 0003. Yeah, ecpg's coverage report is fairly sad overall, but a lot of the uncovered stuff is autogenerated grammar productions, which I think we can have high confidence in. I'm not currently feeling motivated to try to improve that number. regards, tom lane