Opened 10 years ago

Closed 10 years ago

Last modified 5 years ago

#3874 closed merge (fixed)

GHC.Exts.traceEvent segfaults

Reported by: cjs Owned by: igloo
Priority: high Milestone: 6.12.2
Component: Runtime System Version: 6.12.1
Keywords: event, eventlog Cc:
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: Runtime crash Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

When I call the GC.Exts.traceEvent function (argument: "hello") with event logging enabled (i.e., compiled with -eventlog and run with -ls) my program generates a segmentation fault. Here is the gdb backtrace:

#0  0x00007f3ad6744a2f in vfprintf () from /lib/libc.so.6
#1  0x00007f3ad677039a in vsnprintf () from /lib/libc.so.6
#2  0x00000000004476c4 in postLogMsg (eb=0x8160d0, type=19, 
    msg=0x7f3ad5d7e010 "hello", ap=0x0) at rts/eventlog/EventLog.c:403
#3  0x0000000000447853 in postUserMsg (cap=0x69b780, 
    msg=0x7f3ad5d7e010 "hello") at rts/eventlog/EventLog.c:433
#4  0x000000000043b012 in traceUserMsg (cap=0x69b780, 
    msg=0x7f3ad5d7e010 "hello") at rts/Trace.c:290
#5  0x000000000044e237 in stg_traceEventzh ()
#6  0x0000000000000000 in ?? ()

It's not at all clear to me what could be going wrong here.

Attachments (1)

3874-1.patch (1.8 KB) - added by cjs 10 years ago.
Fix segfaults with eventlog user messages due to bad va_args. These were due to bad va_args, either because the default configuration was bad, or because we tried to interpret rather than ignore printf format strings in the user messages.

Download all attachments as: .zip

Change History (10)

comment:1 Changed 10 years ago by cjs

Oh, and for further fun, I've walked through the calls from traceMessage down, and I don't see anywhere where we check for format specifiers in the string the user passes in. I think we want to change this function:

void postUserMsg(Capability *cap, char *msg)
{
    postLogMsg(&capEventBuf[cap->no], EVENT_USER_MSG, msg, NULL);
}

to have the body

    postLogMsg(&capEventBuf[cap->no], EVENT_USER_MSG, "%s", msg, NULL);

comment:2 Changed 10 years ago by cjs

"You can't call varargs functions like that," at least not on this system. Also, we need to fix that printf format args issue. So here's your new code:

void postUserMsg(Capability *cap, char *msg)
{
    postFormatUserMsg(cap, "%s", msg);
}

static void postSafeuserMsg(Capability *cap, char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    postLogMsg(&capEventBuf[cap->no], EVENT_USER_MSG, format, ap);
    va_end(ap);
}

Note that there are a few other places in the code where you'll have to do similar things, such as in rts/Trace.c the call to traceCap_stderr in traceUserMsg.

comment:3 Changed 10 years ago by cjs

Type of failure: None/UnknownRuntime crash

Changed 10 years ago by cjs

Attachment: 3874-1.patch added

Fix segfaults with eventlog user messages due to bad va_args. These were due to bad va_args, either because the default configuration was bad, or because we tried to interpret rather than ignore printf format strings in the user messages.

comment:4 Changed 10 years ago by cjs

My earlier "postSafeuserMsg" patch was wrong in several ways; instead use the attachment just added now, 3874-1.patch, which is tested and fixes more bugs. With a test program main = traceEvent "hello", this fixes the following cases that were previously segfaulted:

ghc        -eventlog -o test test.hs && ./test +RTS -ls
ghc -debug -eventlog -o test test.hs && ./test +RTS -ls -v

However, the following test case still segfaults:

ghc        -eventlog -o test test.hs && ./test +RTS -ls -v

The backtrace for this case is quite different:

#0  0x000000000043dcef in postSchedEvent ()
#1  0x00000000004358a6 in createThread ()
#2  0x000000000044e759 in createIOThread ()
#3  0x000000000044e812 in rts_evalLazyIO ()
#4  0x0000000000430d11 in real_main ()
#5  0x0000000000430e1f in hs_main ()
#6  0x00007f1df3e245a6 in __libc_start_main () from /lib/libc.so.6
#7  0x0000000000402f09 in _start () at ../sysdeps/x86_64/elf/start.S:113

I had a quick look here, and the problem does not appear to be the same va_list issue.

comment:5 Changed 10 years ago by simonmar

Milestone: 6.12.2
Owner: set to simonmar
Priority: normalhigh
Status: newassigned

comment:6 Changed 10 years ago by simonmar

Fixed, thanks:

Fri Feb 26 09:32:15 GMT 2010  Simon Marlow <marlowsd@gmail.com>
  * Fix crash when using printf format specifiers in traceEvent (#3874)

I have a fix for the crash with +RTS -ls -v coming shortly.

comment:7 Changed 10 years ago by simonmar

Owner: changed from simonmar to igloo
Status: assignednew
Type: bugmerge

Fix for the crash:

Fri Feb 26 11:06:08 GMT 2010  Simon Marlow <marlowsd@gmail.com>
  * Tweak the tracing flags slightly, and clean up error handling and diagnostics

I think we could merge this into 6.12.2, since the changes to flags are minor and don't affect the common uses (i.e. +RTS -ls still works the same as before).

comment:8 Changed 10 years ago by igloo

Resolution: fixed
Status: newclosed

Both merged.

comment:9 Changed 5 years ago by Austin Seipp <austin@…>

In a82364c9410d35fa9cb5031d553212267c3628c5/ghc:

Don't truncate traceEvents to 512 bytes (#8309)

Summary:
Don't call postLogMsg to post a user msg, because it truncates messages to
512 bytes.

Rename traceCap_stderr and trace_stderr to vtraceCap_stderr and trace_stderr,
to signal that they take a va_list (similar to vdebugBelch vs debugBelch).

See #3874 for the original reason behind traceFormatUserMsg.

See the commit msg in #9395 (d360d440) for a discussion about using
null-terminated strings vs strings with an explicit length.

Test Plan:
Run `cabal install ghc-events` and inspect the result of `ghc-events show` on
an eventlog file created with `ghc -eventlog Test.hs` and `./Test +RTS -l`,
where Test.hs contains:

```
import Debug.Trace
main = traceEvent (replicate 510 'a' ++ "bcd") $ return ()
```

Depends on D655.

Reviewers: austin

Reviewed By: austin

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D656

GHC Trac Issues: #8309
Note: See TracTickets for help on using tickets.