summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorZejun Wu <watashi@fb.com>2018-11-22 11:51:15 -0500
committerBen Gamari <ben@smart-cactus.org>2018-11-22 13:14:01 -0500
commit390df8b51b917fb6409cbde8e73fe838d61d8832 (patch)
tree68c81cf31c7ceed3f69f8d9cdb07fe79db2152b8 /rts
parent599eaada382d04722219bfc319bde94591be3fb1 (diff)
downloadhaskell-390df8b51b917fb6409cbde8e73fe838d61d8832.tar.gz
Fix uninformative hp2ps error when the cmdline contains double quotes
The format of hp file didn't allow double quotes inside strings, and under prof build, we include args in JOB, which may have double quotes. When this happens, the error message is confusing to the user. This can also happen under normal build if the executable name contains double quite, which is unlikely though. We fix this issue by introducing escaping for double quotes inside a string by repeating it twice. We also fix a buffer overflow bug when the length of the string happen to be multiple of 5000. Test Plan: new tests, which used to fail with error message: ``` hp2ps: "T15904".hp, line 2: integer must follow identifier ``` use new ghc and hp2ps to profile a simple program. Reviewers: simonmar, bgamari, erikd Reviewed By: simonmar Subscribers: rwbarton, carter GHC Trac Issues: #15904 Differential Revision: https://phabricator.haskell.org/D5346
Diffstat (limited to 'rts')
-rw-r--r--rts/ProfHeap.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index de3d2b6aa5..517702f241 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -361,6 +361,18 @@ void endProfiling( void )
#endif /* !PROFILING */
static void
+printEscapedString(const char* string)
+{
+ for (const char* p = string; *p != '\0'; ++p) {
+ if (*p == '\"') {
+ // Escape every " as ""
+ fputc('"', hp_file);
+ }
+ fputc(*p, hp_file);
+ }
+}
+
+static void
printSample(bool beginSample, StgDouble sampleValue)
{
fprintf(hp_file, "%s %f\n",
@@ -428,16 +440,18 @@ initHeapProfiling(void)
initEra( &censuses[era] );
/* initProfilingLogFile(); */
- fprintf(hp_file, "JOB \"%s", prog_name);
+ fprintf(hp_file, "JOB \"");
+ printEscapedString(prog_name);
#if defined(PROFILING)
- {
- int count;
- for(count = 1; count < prog_argc; count++)
- fprintf(hp_file, " %s", prog_argv[count]);
- fprintf(hp_file, " +RTS");
- for(count = 0; count < rts_argc; count++)
- fprintf(hp_file, " %s", rts_argv[count]);
+ for (int i = 1; i < prog_argc; ++i) {
+ fputc(' ', hp_file);
+ printEscapedString(prog_argv[i]);
+ }
+ fprintf(hp_file, " +RTS");
+ for (int i = 0; i < rts_argc; ++i) {
+ fputc(' ', hp_file);
+ printEscapedString(rts_argv[i]);
}
#endif /* PROFILING */