New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

segfault in cast_.d line 59 or 71 when casting class with struct containing union #989

Closed
tosttost opened this Issue Jul 7, 2015 · 4 comments

Comments

Projects
None yet
2 participants
@tosttost

tosttost commented Jul 7, 2015

The following works with dmd 2.067, gdc, ldc 0.15.0-alpha1, ldc 0.15.0-beta1 and ldc 0.15.1. With 0.15.2 beta1 and beta2 (only tested with without optimizations and -g on/off) it segfaults in cast_.d line 71 or line (see comments in code). This issue crashes my vibe.d server on the first request and the following is manually reduced from vibe.d source - therefore the names.
app.d:

import core.sys.posix.netinet.in_;

struct NetworkAddress {
    // if this union is removed, the segfault disappears.
    union {
        sockaddr addr;
        sockaddr_in addr_ip4;
        sockaddr_in6 addr_ip6;
    }
} 

interface InputStream { }

interface OutputStream { }

// if ': InputStream, OutputStream' is removed,
//  the segfault moves from cast_.d line 71 to cast_.d line 59
interface Stream : InputStream, OutputStream { }

interface TCPConnection : Stream { }

class Libevent2TCPConnection : TCPConnection {
    // if m_localAddress or m_removeAddress is removed, 
    //  the segfault disappears
    NetworkAddress m_localAddress, m_remoteAddress;
}

void main() {
    // use auto or Libevent2TCPConnection instead of TCPConnection 
    //  and the segfault disappears.
    TCPConnection conn = new Libevent2TCPConnection();
    Stream s = conn;
} 

I am using Linux x86_64.
Valgrind output:
==3444== Invalid read of size 8
==3444== at 0x4124EC: d_dynamic_cast (cast.d:71)
==3444== by 0x4124A2: d_interface_cast (cast.d:62)
==3444== by 0x401E35: _Dmain (app.d:32)
==3444== by 0x4119C3: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in [somepath]/app)
==3444== by 0x411888: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (dmain2.d:375)
==3444== by 0x411926: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (dmain2.d:400)
==3444== by 0x411888: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (dmain2.d:375)
==3444== by 0x4117EE: _d_run_main (dmain2.d:408)
==3444== by 0x401F57: main (in [somepath]/app)
==3444== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3444==
==3444==
==3444== Process terminating with default action of signal 11 (SIGSEGV)
==3444== Access not within mapped region at address 0x0
==3444== at 0x4124EC: d_dynamic_cast (cast.d:71)
==3444== by 0x4124A2: d_interface_cast (cast.d:62)
==3444== by 0x401E35: _Dmain (app.d:32)
==3444== by 0x4119C3: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in [somepath]/app)
==3444== by 0x411888: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (dmain2.d:375)
==3444== by 0x411926: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (dmain2.d:400)
==3444== by 0x411888: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (dmain2.d:375)
==3444== by 0x4117EE: _d_run_main (dmain2.d:408)
==3444== by 0x401F57: main (in [somepath]/app)

As it works with other compilers and old ldc versions and does not use variadic functions, I do not think this is related to #623 .

@redstar

This comment has been minimized.

Show comment
Hide comment
@redstar

redstar Jul 9, 2015

Member

Confirmed. Crashes with 0.15.2-beta2 but not with 0.15.1.

Member

redstar commented Jul 9, 2015

Confirmed. Crashes with 0.15.2-beta2 but not with 0.15.1.

@redstar

This comment has been minimized.

Show comment
Hide comment
@redstar

redstar Jul 10, 2015

Member

I created this bug with commit 0449b26.

Member

redstar commented Jul 10, 2015

I created this bug with commit 0449b26.

redstar added a commit to redstar/ldc that referenced this issue Jul 12, 2015

Use a byte array for padding of unions/structs.
The previous approach was to add i64, i32, i16, i8 members depending
on alignment and required space. This seems to cause several problems.
Solution is to use a byte array. This makes to code more compact, too.

Fixes issue ldc-developers#989.
@redstar

This comment has been minimized.

Show comment
Hide comment
@redstar

redstar Jul 12, 2015

Member

BTW: Thanks for the nice reduced test case!

Member

redstar commented Jul 12, 2015

BTW: Thanks for the nice reduced test case!

@redstar redstar added this to the 0.15.2 milestone Jul 12, 2015

@redstar

This comment has been minimized.

Show comment
Hide comment
@redstar

redstar Jul 12, 2015

Member

Fixed in master now.

Member

redstar commented Jul 12, 2015

Fixed in master now.

@redstar redstar closed this Jul 12, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment