Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Debugging using Shared Memory (or not)

Author
Message
ShellfishGames
11
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 28th Oct 2014 14:12 Edited at: 29th Oct 2014 12:27
Hi guys,

I'm working on a rather big project right now, and a problem occured - it just freezes every now and then. No error message whatsoever, the game just stops. So I guess there's an infinite loop somewhere, but I can't tell at what point exactly, and I don't want to go through 8k lines of code command by command in order to find out what exactly might not be working. On top of that, the game crashes on a different PC regularly, also without giving me any information why that happens.

DBPs debug mode doesn't work (it always just crashes as soon as the exe is executed), so I have to find my own way to deal with the problem.

My first idea was to basically log somehow what the program is doing, i.e. multiple times throughout the main loop log a number (or string), so that when the game crashes, I'll be able to see what part of the program was responsible by the last number that was logged. Now there may be several ways to do this.

1. Using the Windows Clipboard (write to clipboard, then simply using CTRL+V to find out what was logged last) - this works, but I don't like the idea of writing stuff to the clipboard several thousand times a second. That just doesn't seem right.

2. Writing everything to a file. Not a good idea, as the file would get really huge. Also I'm not sure if the file would even be readable and complete afterwards, as obviously no close file command is executed when the program crashes.

3. And that in theory is my favorite method, but it doesn't work (yet): Using shared memory and a second exe to check what's logged there. Should basically behave like this:
-1. the game allocates memory (e.g. an integer, i.e. p = make memory(4))
-2. it creates a file and writes the pointer adress to that file (open to write 1, "myfile" : write long 1, p : close file 1)
-3. The second program waits until "myfile" exists, then opens the file, gets the pointer
-4. From then on the second exe constantly outputs that value (do : cls : v = *p : print v : loop)
As opposed to the other two methods (possibly), that wouldn't have any effect on the game's performance whatsoever as it would just write a bunch of values to the RAM each frame. Unfortunately, it doesn't work though, as the memory created with make memory(4) isn't shared. Hence the second exe simply crashes because it tries to access memory it's not allowed to read.
Now, I have no idea how to set up a block of shared memory in DBP. Apparently matrix1utils 1 has shared memory banks, but I can't find anything about how to create one in the help files. There's a get bank shared name$() function, and that's all I could find.

Can anybody help me out? Either with how to properly create and use shared memory in DBP, or with a better solution to my debugging problem. Would be highly appreciated.

Thanks in advance,
Shellfish Games

TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 28th Oct 2014 20:00
First off, if you have to log something 1000 times a second then you're doing something wrong. You should log only major state changes (such as loading objects, playing sounds, major collision events, switching animation states? Stuff like that.)

In my experience, the only thing I've seen cause DBP to exit without error are failed shaders and sometimes plugins.

You are correct that exiting without calling close file can cause parts of the file not to be written. Matrix1 Utils has commands to flush the input buffer directly to disk:


This is some old code from an RTS game I once wrote, it produces a HTML log. You're free to base your ideas off of and/or copy the entire thing into your project:
https://bitbucket.org/TheComet/ponycraft-prototype/src/4046f85e02c0ae50837fff217b59b6aa95579bef/source/Debug.dba?at=master

I like offending people. People who get offended should be offended. -- Linus Torvalds
ShellfishGames
11
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 28th Oct 2014 21:29
Thanks for your help, Comet.

Quote: "First off, if you have to log something 1000 times a second then you're doing something wrong."


I just want to find out what part of my main loop causes the problem. This isn't what you typically create a Log for, I just need this work around because the DBP Debugger does not work.
Also, DBP doesn't exit in this case - it simply freezes (no windows error or anything), hence my assumption that it is caused by an infinite loop somewhere.

However, I did solve that error now using the clipboard method. It turned out the infinite loop was set in my particle update function due to inconsistencies caused by deleted emitters.
But another error occured, which is completely different, yet I need the shared memory approach to debug it... because the problem, whatever it is, results in any string operation to crash the program at a certain point, hence the clipboard version doesn't work here, because the attempt to write something to the clipboard itself results in a crash.

So the question remains... how do I set up a block of shared memory in DBP?

MrValentine
AGK Backer
13
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 28th Oct 2014 22:55
Quote: "
File Mapping
Sharing data between multiple programs running on the same computer can often be difficult. The File Map commands provided in the expansion pack makes this process much simpler. When creating a file map a global, shared amount of memory will be set up in the Operating System. This can then be read and written to by a Dark Basic Professional application. Then either other Dark Basic Professional applications or applications written in other programming languages that natively support file mapping can access the shared memory. "


http://www.thegamecreators.com/?m=view_product&id=2083

ShellfishGames
11
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 29th Oct 2014 00:02 Edited at: 29th Oct 2014 12:27
But there surely must be a solution that doesn't cost $20 to access such a funtamental feature as shared memory in DBP..?

... OK, I just dug a little deeper into the matrix1utils commands, and it seems I simply overlooked the relatively obvious command "map shared mem to bank", which does just what I need.
As an example, these two programs communicate perfectly fine:

1. The "Host", setting up the bank and writing values to it


And 2. the "Client", reading values from the bank:


So, I think I can use this to debug my program. Thanks for your help.

Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 29th Oct 2014 02:32
You can use any debugger to at least uncover the root cause of your problems, then work from that. Sometimes it isn't very easy when you don't have access to any debug symbols, but it can still tell you if you have a null dereference, an access violation error, or something else. This helps limit the possible causes in your code.

As for what you are describing, I usually either print to a console window (IanM's M1U pack has this functionality) or display a message box (use any plugin featuring those or call MessageBoxA from user32.dll directly) at various key places in the code. In this manner I can determine that the crash happened "after log point 12" and then gradually limit the sought scope logarithmically by just reducing the log space in two for each test. Finally you will end up with a few, or even just a single, line(s) that cause the actual crash.

There is no particular need to use any shared memory and double programs for this at all, yet if you truly want to there are functions in the Windows API that lets you read memory from other processes (this is used by memory scanners such as CheatEngine if you've ever heard of that).
It seems like you just want a designated memory area that is shared though. You could use a database system, a TCP connection or even the registry to share a simple value between two applications, especially if only one of them will be writing the value and the other one will only read it.


If you really want a shared memory solution still I can try writing some simple example code tomorrow.

ShellfishGames
11
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 29th Oct 2014 12:24
Thanks Rudolpho.

Quote: "As for what you are describing, I usually either print to a console window (IanM's M1U pack has this functionality) or display a message box (use any plugin featuring those or call MessageBoxA from user32.dll directly) at various key places in the code. In this manner I can determine that the crash happened "after log point 12" and then gradually limit the sought scope logarithmically by just reducing the log space in two for each test. Finally you will end up with a few, or even just a single, line(s) that cause the actual crash.
"


That's usually how I do it as well - either using print <..> : sync : wait key, or using message. However, the initial error happened rarely, often after a few minutes of playing, and I needed to find out what part of the main loop causes it. So I'd have to click through thousands and thousands of messages until the error occurs - if at all (I had it more than once that the mere existence of debug messages prevented a bug from occurring at all). That's why I needed a fast solution running in the background that I could check after the crash.

Quote: "If you really want a shared memory solution still I can try writing some simple example code tomorrow."


I highly appreciate it, but as I said in the post just before yours that you might not have seen, I implemented a working shared memory solution using the matrix1 plugin, so that's not necessary anymore.
In fact, replacing my old clipboard based debugging with this shared memory based approach for some reason eliminated the weird string based crashes I had, so right now, everything just seems to work fine surprisingly enough.

Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 29th Oct 2014 17:09
I see, well when errors occur like that the actual crash usually isn't related to the actual fault in an obvious way sadly (it can be things like a lingering pointer which isn't accessed until somewhere else, but at that point it will be hard to relate to what may have released the pointer prematurely and so on). Good luck debugging, hope you trace it down!

Quote: "I highly appreciate it, but as I said in the post just before yours that you might not have seen, I implemented a working shared memory solution using the matrix1 plugin, so that's not necessary anymore."

Ah yes, a quirk of mine is to begin writing a reply, then take a lunch / dinner break and completely forget about it for many hours; I actually begun writing my response when there were only two posts in this thread

pcRaider
16
Years of Service
User Offline
Joined: 30th May 2007
Location:
Posted: 31st Oct 2014 08:32 Edited at: 31st Oct 2014 08:35
DBP's File Mapping command





READ FILEMAP STRING() : Return String=READ FILEMAP STRING(String Value)
READ FILEMAP VALUE() : Return DWORD=READ FILEMAP VALUE(Filemap Name)
WRITE FILEMAP STRING : WRITE FILEMAP STRING Filemap Name, String
WRITE FILEMAP VALUE : WRITE FILEMAP VALUE Filemap Name, Value

windowsXp
ShellfishGames
11
Years of Service
User Offline
Joined: 6th Feb 2013
Location:
Posted: 31st Oct 2014 13:30
Wow. Where did they come from?! Seem to be undocumented(?), but do indeed compile. Fascinating, thank you.

pcRaider
16
Years of Service
User Offline
Joined: 30th May 2007
Location:
Posted: 1st Nov 2014 05:13
File Mapping

Read comment of Chris Tate.
http://forum.thegamecreators.com/?m=forum_view&t=205533&b=1

windowsXp

Login to post a reply

Server time is: 2024-04-18 19:14:53
Your offset time is: 2024-04-18 19:14:53