how to reduce a debug symbol error?

2011-06-28 Thread Trass3r

Starting my cl4d executable with 'gdb main -readnow' results in

Reading symbols from main...expanding to full symbols...Die:  
DW_TAG_type_unit (abbrev 4, offset 0x6a)

  parent at offset: 0xb
  has children: FALSE
  attributes:
DW_AT_byte_size (DW_FORM_data1) constant: 16
DW_AT_type (DW_FORM_ref4) constant ref: 0x62 (adjusted)
Dwarf Error: Missing children for type unit [in module main]

How do you reduce/report such a bug?


r/w binary

2011-06-28 Thread Joel Christensen
I want to save and load levels for my game. The std.stream module 
doesn't have much examples.


Here is my code:
void saveLevel( string fileName ) {
auto bfile = new std.stream.File;

int ver = 1;
string verStr = "version:";
with( bfile ) {
scope( exit )
close;
create( fileName );
write( verStr ); write( ver ); // version
}

int ver2;
char[] verStr2;
auto bfile2 = new std.stream.File;
with( bfile2 ) {
scope( exit )
close;
create( fileName );
read( verStr2 ); read( ver2 ); // version
}
writeln( verStr, ver );
}

And this is the result:
std.stream.ReadException@std\stream.d(46): Stream is not readable

- Joel


Re: how to reduce a debug symbol error?

2011-06-28 Thread Robert Clipsham

On 28/06/2011 22:47, Trass3r wrote:

Starting my cl4d executable with 'gdb main -readnow' results in

Reading symbols from main...expanding to full symbols...Die:
DW_TAG_type_unit (abbrev 4, offset 0x6a)
parent at offset: 0xb
has children: FALSE
attributes:
DW_AT_byte_size (DW_FORM_data1) constant: 16
DW_AT_type (DW_FORM_ref4) constant ref: 0x62 (adjusted)
Dwarf Error: Missing children for type unit [in module main]

How do you reduce/report such a bug?


First: are you compiling *all* modules with -gc rather than -g?

Once you've checked that, what OS/platform are you on? Posting a binary 
will most likely be enough to fix it, but given that there's no way to 
check it's fixed without some source to work with it may be best to 
narrow down a test case.


To do that, I recommend you unleash DustMite on your source: 
https://github.com/CyberShadow/DustMite. You'll need a script that can 
test for the bug too, you can pass a command file to gdb and grep for 
the relevant failure, alternatively if you can get the failure when 
using dwarfdump/objdump that may be easier.


If your code's open source you could always just put a link to your 
source code on there, it won't take long for someone else to narrow down 
a test case if they know what they're doing (it wouldn't be the first 
time I've narrowed down several thousand lines of code to fix dmd's 
debug info :>).


--
Robert
http://octarineparrot.com/


Re: how to reduce a debug symbol error?

2011-06-28 Thread Trass3r

First: are you compiling *all* modules with -gc rather than -g?


Ah ok, somehow I was mislead into thinking that the gdb patches allow you  
to use -g.


It works now though line numbers are more messed up than I'm used to from  
cv2pdb + VS. There I only have the usual problems with mixins but here it  
even jumps around senselessly if I just do a step over.

Don't know if this has to do with -gc or Descent.


To do that, I recommend you unleash DustMite on your source:  
https://github.com/CyberShadow/DustMite. You'll need a script that can  
test for the bug too, you can pass a command file to gdb and grep for  
the relevant failure, alternatively if you can get the failure when  
using dwarfdump/objdump that may be easier.


Yeah need to test that tool soon.


Win32 Application Error

2011-06-28 Thread Loopback

Hi!

I've recently been using D to program win32 executables. On the official
D site (d-programming-language.org) there is a template of how a basic
win32 executable is supposed to be. In this template you are supposed to
initialize and terminate the D runtime. If I understand correctly this
runtime is related to garbage collection and static con- and
destructors.

This snippet below from my own code works perfectly fine at my
other computer (though both of my computers uses the exact same OS;
win7 x64 Ultimate).

My problem occurs when I terminate the runtime. With one of my computers
it works flawlessly, while on this computer the application hangs up on
exit. I've debugged the code located it to where I terminate the
runtime. The application stops responding completely. Now the
interesting part is that the application do close, but the process still
runs. So you do not notice it at all practically, until you check in the
task manager. The process ends after a while, varying from 5 seconds to
50 seconds.

This is what happens if I press the close button (in the corner). If I
close the program with PostQuitMessage(0) instead, the application is
still visible but a "Program is not resonding" appears. This also
happens at "runtime terminate".

So my question is; how should I avoid these "process still running" and
program not responding errors?

(if worth mentioning, the program itself works perfectly fine, it is
just at exit the program 'bugs').

The code below is my main.d file.

// Win32 Imports
import win32.windef;
import win32.winuser;

// STD&Core Includes
import core.runtime;
import std.utf;

// Custom Includes
import cwindow;
import global;

// Application Entry Point
extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE 
hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{
int result;

void exceptionHandler(Throwable e) { throw e; }

try
{
// Start Runtime
Runtime.initialize(&exceptionHandler);

// Create Application
CWindow wndw = new CWindow(hInstance);

// Control Object
if(wndw !is null)
result = 1;

// Terminate Runtime
Runtime.terminate(&exceptionHandler); // It always crashes here
}

catch(Throwable o)
{
		MessageBoxW(null, o.toString().toUTF16z, "Error", MB_OK | 
MB_ICONEXCLAMATION);

result = 0;
}

return result;
}


Re: Win32 Application Error

2011-06-28 Thread Andrej Mitrovic
It's hard to tell what's going on when we can't see the code for
CWindow. Otherwise your code seems to be the same as the template so
that part should be fine.

Otherwise if you're using multithreading it might be a good idea to
call ExitProcess(result) after PostQuitMessage(), as calling
PostQuitMessage() alone will not terminate any background threads that
you've spawned from D which are looping infinetly.


Problem with a convoluted templated struct

2011-06-28 Thread Kiith-Sa
Hello.

I am trying to implement a templated struct containing a
data member created by std.variant.Algebraic instantiated
with the struct's template parameters. 

The problem is, I want to template the struct with e.g. 
arrays (lists, etc.) of its own type. I don't know
any way to do this without ugly string mixin code.

I'm not sure if I can explain this clearly, so here's some code:



import std.variant;

struct Node(Types ...)
{
Algebraic!(Types) value;

//other members, etc...
}

unittest
{
//this works
Node!(string, int) node1;

//this is what I want, but I can't do it, since
//Node must be templated
Node!(Node[], string, int) node1;
}


//Now, I can get around this with a string mixin:
//(just one argument in this example, but it
// could be variadic with more complex code)


struct Node2(string t)
{
mixin("private alias " ~ t ~ " Type;");
Algebraic!(Type) value;
}

unittest
{
//works, but ugly
Node2!("Node2[]") node;
}



Is there any way to do this without string mixins?
(in case this is proposed: I specifically need structs, not classes.
I know I could do this with templated derived classes storing
an array/list/whatever with parent class type.


Thanks for any help.


Re: Win32 Application Error

2011-06-28 Thread Loopback

Thank you for your reply!

I do not use multi-threading so it is not related to that. Though I do
have located the error. It seems as if the application only hangs/delays
application exit, when I load a texture file with DirectX. To be
specific, the function in this case is D3DXCreateTextureFromFileExW.

I still do not see though why the terminate function call fails. Since
the same code works on my other computer. I've also used DirectX debug,
and checking all HRESULTs (success or failure basically). The DirectX
debug output does not display any errors nor warnings and all HRESULTs
returns successfully. The texture loaded with the function does also
work flawlessly, likewise the free memory functions for the textures.

Below is the code that I use for loading and releasing textures:

class (...)

IDirect3DTexture9 LoadTexture(IDirect3DDevice9 device, string fileName, 
D3DXIMAGE_INFO * info = NULL)

{
// Check if the texture has already been allocated
IDirect3DTexture9 * pTexture = (fileName in m_textures);

// Return it then
if(pTexture !is null)
return *pTexture;

// If not, create a new one
IDirect3DTexture9 texture;

// Allocate It
	if(FAILED(D3DXCreateTextureFromFileExW(device, fileName.toUTF16z, 
D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, 
D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, info, NULL, &texture)))

return null;

// Return it
return m_textures[fileName] = texture;
}

void Destroy()
{
foreach(string key; m_textures.keys)
m_textures[key].Release();
}

// The associative array
IDirect3DTexture9[string] m_textures;



Re: Win32 Application Error

2011-06-28 Thread Loopback

One more thing, would it perhaps help if I supplied a delegate to
the terminate function, since that may output debug messages?

I would gladly try it but I am not sure how this supplied delegate is
supposed to be.

Also want to mention that the initialize functions returns successfully.


Interfacing to C

2011-06-28 Thread Joshua Niehus
Hello,

I was trying to run the example on the Interfacing to C page (
http://www.d-programming-language.org/interfaceToC.html) and ran into few
issues. To get it to work "as is" i was .dup(ing) strings into new chars
with defined size and passing those with .ptr. Anyway it seemed like quite a
bit of work for something simple so I added const in the signatures and
things worked much more smoothly:

import std.stdio, std.string;

extern (C) int strcmp(const char* string1, const char* string2);

void main()
{
writeln(myDfunction("foo"));
}

int myDfunction(const char[] s) {
return strcmp(std.string.toStringz(s), "foo");
}

Was there a reason why the consts were left out?
if this is a typo I'd be happy to update the web page, would be good
experience for a noob like me. (never used GIT before and first time
participating in a community)

Thanks,
Josh


Re: Interfacing to C

2011-06-28 Thread Jimmy Cao
On Tue, Jun 28, 2011 at 11:15 PM, Joshua Niehus  wrote:

> Hello,
>
> I was trying to run the example on the Interfacing to C page (
> http://www.d-programming-language.org/interfaceToC.html) and ran into few
> issues. To get it to work "as is" i was .dup(ing) strings into new chars
> with defined size and passing those with .ptr. Anyway it seemed like quite a
> bit of work for something simple so I added const in the signatures and
> things worked much more smoothly:
>
> import std.stdio, std.string;
>
> extern (C) int strcmp(const char* string1, const char* string2);
>
> void main()
> {
> writeln(myDfunction("foo"));
> }
>
> int myDfunction(const char[] s) {
> return strcmp(std.string.toStringz(s), "foo");
> }
>
> Was there a reason why the consts were left out?
> if this is a typo I'd be happy to update the web page, would be good
> experience for a noob like me. (never used GIT before and first time
> participating in a community)
>
> Thanks,
> Josh
>


I think it was written for D1, where strings are char[].
The code can be written like this:

import std.string;

extern (C) int strcmp(const char* string1, const char* string2);

int myDfunction(string s) {
return strcmp(toStringz(s), "foo");
}


Re: Problem with a convoluted templated struct

2011-06-28 Thread Ali Çehreli
On Wed, 29 Jun 2011 04:06:02 +0200, Kiith-Sa wrote:

> Hello.
> 
> I am trying to implement a templated struct containing a data member
> created by std.variant.Algebraic instantiated with the struct's template
> parameters.
> 
> The problem is, I want to template the struct with e.g. arrays (lists,
> etc.) of its own type. I don't know any way to do this without ugly
> string mixin code.
> 
> I'm not sure if I can explain this clearly, so here's some code:
> 
> 
> 
> import std.variant;
> 
> struct Node(Types ...)
> {
> Algebraic!(Types) value;
> 
> //other members, etc...
> }
> 
> unittest
> {
> //this works
> Node!(string, int) node1;
> 
> //this is what I want, but I can't do it, since //Node must be
> templated
> Node!(Node[], string, int) node1;
> }
> 
> 
> //Now, I can get around this with a string mixin: //(just one argument
> in this example, but it // could be variadic with more complex code)
> 
> 
> struct Node2(string t)
> {
> mixin("private alias " ~ t ~ " Type;"); Algebraic!(Type) value;
> }
> 
> unittest
> {
> //works, but ugly
> Node2!("Node2[]") node;

That works because the name Node2 represents the complete type of the 
templated struct in the struct definition.

> }
> 
> 
> 
> Is there any way to do this without string mixins? (in case this is
> proposed: I specifically need structs, not classes. I know I could do
> this with templated derived classes storing an array/list/whatever with
> parent class type.
> 
> 
> Thanks for any help.

Providing the container type as an alias template parameter seems to work:

import std.container;
import std.variant;

struct MyAlgebraic(Types ...)
{}

struct MyList(T)
{}

struct Node(alias ContainerType, Types ...)
{
ContainerType!Node container;
MyAlgebraic!(Types) value;
}

unittest
{
Node!(Array, string, int) node1;
Node!(MyList, double, char) node2;
}

void main()
{}

But I hit other compilation problems in Algebraic, which I believe to be 
const-correctness issues.

Also consider looking at Phobos ranges. Instead of templatizing on the 
container type, templatizing on the range type may be better.

Ali


Obtaining aligned addresses and aligned spaces for objects

2011-06-28 Thread Ali Çehreli
The address that is passed to emplace() must be properly aligned for that 
type. Am I correct in thinking that the following functions are a must? 
If so, do you think that they are correct? If so, are there equivalents 
in Phobos?

/**
 * Return an aligned address for the type at or after the
 * candidate address.
 */
T * alignedAddress(T)(T * candidate)
{
return cast(T*)((cast(size_t)candidate + T.alignof - 1)
/ T.alignof * T.alignof);
}

/**
 * A convenient overload for void*
 */
void * alignedAddress(T)(void * candidate)
{
return alignedAddress(cast(T*)candidate);
}

/**
 * Return the size of the space that the type occupies from
 * one aligned address to the next.
 */
size_t alignedSpace(T)()
{
static if (is (T == class)) {
size_t size = __traits(classInstanceSize, T);
} else {
size_t size = T.sizeof;
}

return cast(size_t)alignedAddress(cast(T*)size);
}

Here is the rest of the program that uses those:

import std.stdio;
import core.memory;
import std.conv;

struct S
{
string s;

string toString()
{
return s;
}
}

void main()
{
/* Inputs to use to make objects */
string[] inputs = [ "hello", "world" ];

/* Raw memory */
S * chunk = cast(S*)GC.calloc(inputs.length * alignedSpace!S());

/* Make objects */
foreach (i, str; inputs) {
S * objectAddress = alignedAddress(chunk + i);
emplace(objectAddress, str);
}

/* Convert from pointer to slice. Nice feature! :) */
S[] objects = chunk[0 .. inputs.length];

/* Use the objects */
writeln(objects);
}

The output:

[hello, world]

On a related note, why doesn't __traits(classInstanceSize, T) consider 
the padding bytes? If I'm not mistaken struct sizes do include the 
padding bytes. The following class has the very odd size of 17! Is that 
by design?

class C
{
char c;
}

void main()
{
assert(__traits(classInstanceSize, C) == 17);
}

Ali


Re: r/w binary

2011-06-28 Thread Ali Çehreli
I've settled on std.stdio as opposed to std.stream and std.cstream.

On Wed, 29 Jun 2011 10:07:13 +1200, Joel Christensen wrote:

> I want to save and load levels for my game. The std.stream module
> doesn't have much examples.
> 
> Here is my code:
> void saveLevel( string fileName ) {
>   auto bfile = new std.stream.File;
> 
>   int ver = 1;
>   string verStr = "version:";
>   with( bfile ) {
>   scope( exit )
>   close;
>   create( fileName );
>   write( verStr ); write( ver ); // version
>   }
> 
>   int ver2;
>   char[] verStr2;
>   auto bfile2 = new std.stream.File;
>   with( bfile2 ) {
>   scope( exit )
>   close;
>   create( fileName );

That is copy-paste mistake, right? You don't want create() before 
reading. You must have meant open:

open( fileName );

It works with that change.

>   read( verStr2 ); read( ver2 ); // version
>   }
>   writeln( verStr, ver );
> }
> 
> And this is the result:
> std.stream.ReadException@std\stream.d(46): Stream is not readable
> 
> - Joel

Ali