2017-12-14 3 views
0

Ich habe den folgenden Code (mit SharpDX.WIC/SharpDX.Direct3D11), die immer eine Ausnahme wirft sagen, es gab eine Zugriffsverletzung.Finden Sie den Ursprung der Zugriffsverletzung in Mixed Code

public static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, BitmapSource bitmapSource) 
{ 
    // Allocate DataStream to receive the WIC image pixels 

    int stride = PixelFormat.GetStride(bitmapSource.PixelFormat, bitmapSource.Size.Width); 
    using (var buffer = new DataStream(bitmapSource.Size.Height * stride, true, true)) 
    { 
     // Copy the content of the WIC to the buffer 
     bitmapSource.CopyPixels(stride, buffer); 
     return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription() 
     { 
      Width = bitmapSource.Size.Width, 
      Height = bitmapSource.Size.Height, 
      ArraySize = 1, 
      BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, 
      Usage = SharpDX.Direct3D11.ResourceUsage.Default, 
      CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, 
      Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, 
      MipLevels = 1, 
      OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, 
      SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), 
     }, new DataRectangle(buffer.DataPointer , stride)); 
    } 
} 

Die Ausnahmemeldung ist:

Ausnahme bei 0x00007FF894ECA25C geworfen (combase.dll) in MyApp.exe: 0xC0000005: Zugriffsverletzung Schreibort 0x0000000000000008.

EDIT: Manchmal habe ich diese Ausnahme statt:

Ausnahme bei 0x00007FF8825283BD (WindowsCodecs.dll) in MyApp.exe geworfen: 0xC0000005: Zugriffsverletzung Leseort 0xFFFFFFFFFFFFFFFF.

Es tritt in dieser Zeile:

bitmapSource.CopyPixels(stride, buffer); 

ich irgendwo gelesen, dass die FormatConverter alle Komponenten erfordert, so zu entsorgen, bevor in einem ungültigen liest den Puffer Ergebnisse zu kopieren. Danach hat es geklappt, ist dann aber ohne sinnvollen Grund wieder kaputtgegangen. Jetzt bekomme ich immer diese Schreibzugriffsverletzung und ich kann die Quelle nicht finden.

Ich versuchte herauszufinden, wo es passiert mit der Demontage, aber ich habe keine Ahnung, wo würde gefunden werden. Schließlich verstehe ich nicht, warum das nicht funktioniert. Der Code dafür stammte von einem älteren SharpDX-Beispielcode, auf den selbst bei Stackoverflow viel referenziert wurde. Aber es funktioniert einfach nicht. Der zugrunde liegende FileStream hat ReadWrite -access und die DataStream ist eingestellt, Lese- und Schreibvorgänge zu ermöglichen.

Könnte dies ein Problem in der Codebasis SharpDX.WIC sein?

Um dies kurz und handlich zu halten, ist here die vollständige Quelle in chronologischer Reihenfolge.

+1

Auf diese Weise schlägt nicht gemanagter Code fehl. Alles, was Sie wirklich wissen, ist, dass jemand mit dem zugrundeliegenden Speicher dieses DataStream schlecht gelaufen ist, da es ein Schreiben war, das fehlgeschlagen ist. Eine Adresse von 8 Hinweisen auf einen Nullzeiger, 0xFF..FF, ist jedoch viel fieser und weist auf einen zufälligen Zeiger hin. Es hat oft nichts mit diesem spezifischen Code zu tun, die durch früheren Code verursachte Speicherbeschädigung ist der übliche Auslöser. Dass dies sehr schwer zu debuggen ist, ist der Hauptgrund dafür, dass managed Code populär wurde. Application Verifier kann hilfreich sein. –

+0

Mögliches Duplikat von [Wie AccessViolationException aus systemeigenem Code zu debuggen] (https://stackoverflow.com/questions/3245185/how-to-debug-accessviolationexception-coming-from-native-code) –

Antwort

0

Meine Vermutung ist, dass einige Zahlen mit Zeigern verschmolzen wurden. wenn jemand

  • 0x0000000000000008
  • 0xFFFFFFFFFFFFFFFF

In integer Form, das sind 8 und -1, so dass es mich nicht im Code überraschen würde: bei der Erinnerung schauen richtet sich mit seinem zugreifen möchten Übergeben Sie numerische Werte, bei denen die API ein IntPtr oder ähnliches erwartet. Ich habe keinen Zugriff auf die bestimmte Bibliothek, mit der Sie arbeiten, aber ich würde mir die Argumenttypen genau ansehen und sicherstellen, dass Sie nicht etwas weitergeben, das sie nicht erwartet (oder falls es solche gibt) An allen Stellen, an denen Sie einen Wert von -1 oder 8 übergeben würden.

+0

Die Signatur dieser Methode ist 'BitmapSource.CopyPixels (int stride, DataPointer dataPointer)' - während der 'DataPointer' implizit der Puffer selbst ist. Es scheint, als wäre das ein Problem auf der Seite von SharpDX, also schätze ich, dass ich es zur Verifizierung auf ihre Issue-Seite auf Github übergebe ... Schließlich habe ich nur den von ihnen bereitgestellten Beispielcode verwendet. – SharpShade

Verwandte Themen