How to write a wrapper?

Started by Midimaster, April 01, 2021, 14:59:29

Previous topic - Next topic

Midimaster

no sound, because you switched off all code line in the callback?

or

no sound because you did not press the mouse?
...back from Egypt

iWasAdam

ok, I can confirm the normal build works but the debug build fails  8)
Is there any way the debug version can be made to function?

Midimaster

I have o idea, why it happens. But I already know the same behaviour from other multi-threads-based blitzmax software.

There are two possible scenarios:

There is a bug in the code, which make the debugger crashing
or...
There is a bug in the debugger

Maybe someone else can us teach the limitations of the debugger?
...back from Egypt

Derron

The debugger surrounds the stuff you "create" in BlitzMax. So you code it and the GC places something before and after. It observes the stack so to show you "what" happened before (when the debugger stops in MaxIDE you see what was "called" before and what the values in there were).

This of course _can_ lead to issues - most probably you do something "faulty" and because the threads now need "longer" (your code lines padded by debugger stuff) it might lead to a delayed GC-ing of element ... elements which now might be in use by something else (because you did not use LockMutex and UnlockMutex...).


To find it out: compile your stuff as "debug" and keep "GDB" information (see MaxIDE compile options).

Then execute your binary this way:
open terminal ("run ... " "cmd")
cd c:\to\your\programme
c:\Path\ToBlitzMax\MinGWx64\bin\gdb.exe -r yourprogramme.exe

(this is done this way to have "yourprogramme" run in the right folder - moving to mingw\bin and starting "gdb.exe -r c:\path\to\your\programme.exe" would run your programme from the gdb folder .... also use "quotation marks" -> "" if your path contains spaces or similar oddities).

it will show something like "gdb>"
type in "r" (for run)
your app will start
it will... crash

now type in "bt" (for backtrace)

it will show a stack of commands with the top being the one where it crashes and below from there stuff "came".

If a lot of information is "optimized out" and you see stuff happened in modules - you need to compile the modules as debug with keeping "gdb" information too. When then recompiling your programme the "optimized out" might partially be filled with actual code lines/numbers of the module.


That "gdb information" means that BCC adds various lines before each command you execute in your blitzmax code (in the transpiled C code you will have extra lines informing the debugger where the original source of the error was before transpiling to C).


Use "q" to quit the gdb (gnu debugger).


This is also the way to go to debug "C"-Code you use in BlitzMax - as the blitzmax debugger only sees the BlitzMax-side of your programme.


bye
Ron

Midimaster

wow, that's interesting. I already see such options like  GDB in the IDe but I dont knwo, what is is and found no manual about it.

In the IDE of BlitzMax NG there are many more of new features for developers, but they forgot to add informations about it in the help file. Or is it avaiable anywhere?

I will try the procedure you descriped. Maybe it is a problem in the C-part of my app.

Does a crash in DEBUG always point to a code problem? Or is it possible that the DEBUGGER itself can be the reason for the problem?

What I want to say: Should all programs run perfect also in debug mode? Or do you know situations where DEBUG mode is not possible anymore?




...back from Egypt

iWasAdam

From my experience debug systems are larger and run slower, so anything to do with threading and timing can cause issues.

But... usually not crashes, just slowdowns. crashes in either debug or release (and not the other) usually point to some unusual situation that is taking place and not being handled.

With QasarBeach (which is now fully threaded) which uses a ring-buffer, the debug version would be fine with a single voice - generally happy with a few voice but get very choppy and sometimes stop - but not crash - with many voices.
All of these things vanish with the release version.

The fact that your code wont run in debug suggests that something is slightly off.

Also beware that macos and windows are very different beasts, and true cross platform always need a few compiler tweaks tailored for each system...

Midimaster

Quote from: Derron on April 30, 2021, 08:22:31
The debugger surrounds ....

Hi, I did the steps you descriped, but I cannot interpret the results I get.

first to say I build my app new in DEBUG-mode. I switched off "Quick build" to really re-complie the whole code. Also I have check signs an: DEBUG BUILD, BUILD GUI APP, VERBOSE BUILD, GDB DEBUG GENERATION and  GPROF PROFILING (dont know whether they all are necessary)

Then I proceed as you sayd. It looks like the GDB was running, but the reslut was not as expected. My app did not crash, but hang without a chance to finish it. It stopped, when I stopped GDB with "q". Before I stopped I tried to get the protocoll with "bt" and this is the result:
Microsoft Windows [Version 10.0.19041.928]
C:\Users\info>cd c:\BasicNG\FreeAudio
c:\BasicNG\FreeAudio>c:\BlitzMaxNG\MinGW32x64\bin\gdb.exe -r PlayNoise.debug.exe
GNU gdb (GDB) 8.1
...
Reading symbols from PlayNoise.debug.exe...expanding to full symbols...(no debugging symbols found)...done.
(gdb) r
Starting program: c:\BasicNG\FreeAudio\PlayNoise.debug.exe
[New Thread 2824.0x950]
[New Thread 2824.0x1ca4]
[New Thread 2824.0x44]
[New Thread 2824.0x1bb4]
[New Thread 2824.0xf34]
[New Thread 2824.0x26f0]
[New Thread 2824.0x18a0]
[New Thread 2824.0x4a8]
[New Thread 2824.0x10ec]
[New Thread 2824.0x9ac]
[New Thread 2824.0xedc]
[New Thread 2824.0xf0]

==the following lines are printf() from my app===================================
START_DEVICE_GLUE
FILL_VALUE_B
CREATE A DEVICE
: Attempting to initialize WASAPI backend...
==end of lines from my app ================================================


[New Thread 2824.0x1688]

==the following lines are printf() from my app ===================================
[miniaudio] SSE2:    YES
[miniaudio] AVX2:    NO
[miniaudio] AVX512F: NO
[miniaudio] NEON:    NO
[WASAPI] Trying IAudioClient3_InitializeSharedAudioStream(actualPeriodInFrames=480)
    defaultPeriodInFrames=480
    fundamentalPeriodInFrames=480
    minPeriodInFrames=480
    maxPeriodInFrames=480
[WASAPI] Using IAudioClient3
    periodSizeInFramesOut=480
==end of lines from my app ========================================


[New Thread 2824.0x1660]

==the following lines are printf() from my app ======================================
INFO: [WASAPI]
INFO:   1 - 32W_LCD_TV (AMD High Definition Audio Device) (Playback)
INFO:     Format:      16-bit Signed Integer -> 32-bit IEEE Floating Point
INFO:     Channels:    2 -> 2
INFO:     Sample Rate: 48000 -> 48000
INFO:     Buffer Size: 480*3 (1440)
INFO:     Conversion:
INFO:       Pre Format Conversion:    NO
INFO:       Post Format Conversion:   YES
INFO:       Channel Routing:          NO
INFO:       Resampling:               NO
INFO:       Passthrough:              NO
==end of lines from my app ======================================



Thread 14 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 2824.0x1660]
0x0000000000837754 in ?? ()
(gdb) bt
#0  0x0000000000837754 in ?? ()
#1  0x000000000073b5ac in ?? ()
#2  0x000000000073b634 in ?? ()
#3  0x000000000040168b in ?? ()
#4  0x000000000044dfed in ?? ()
#5  0x000000000044e442 in ?? ()
#6  0x000000000044f6eb in ?? ()
#7  0x0000000000450789 in ?? ()
#8  0x00007ff8e1137034 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\System32\kernel32.dll
#9  0x00007ff8e12e2651 in ntdll!RtlUserThreadStart () from C:\WINDOWS\SYSTEM32\ntdll.dll
#10 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) q
A debugging session is active.

        Inferior 1 [process 2824] will be killed.

Quit anyway? (y or n) y
error return ../../../../src/gdb-8.1/gdb/windows-nat.c:2830 was 5

c:\BasicNG\FreeAudio>


Wat does this mean? I would have expected more information...
...back from Egypt

Derron

first of all: no need for "gprof profiling" (it creates a relatively big file which you can use with gprof, valgrind or whatever to analyze what function was called how many times and how long execution of it took etc).

BUT ... you need to compile the modules too

bmk makemod -a -d -gdb
(make all modules compiled for "debug" containing "GDB information").


Yet ... if the miniaudio library is crashing, this wont help much (if the stack is so deep that it does not show _where_ from your BMX code it was called).
That library might not be a "debug-build".

"??" means the gnu debugger (gdb) was not able to identify something - the addresses pointed did not contain "valid" pointers or so.

In other words: something you do uses wrong addresses / pointers / ...


Eg. (hope I am not wrong here now) is that if you use a pointer into a specific blitzmax structure, there is to pay attention of 32bit, 64bit ... differences, also an object which looks like an "array of values" might consist of a bit more (struct pointer ... then length, then values ...). People like col might be able to help here.
And of course Brucey - who committed some bcc changes over the weekend so maybe is replying to mails these days (waiting for replies of mine from summer last year)


bye
Ron

Midimaster

#98
At the moment I re-compile the modules. Hoep it will bring some more information to the debugger.


Quote from: Derron on May 03, 2021, 13:14:39
...
BUT ... you need to compile the modules too

bmk makemod -a -d -gdb
(make all modules compiled for "debug" containing "GDB information").

do you mean "makemods" instead of "makemod"?

bmk makemods -a -d -gdb

some questions:

Are this debug lines also added to the c-file? What do you means with "That library might not be a "debug-build"."? What I use is only source code (a single miniaudio.h-file).

and can i "reset" this changes by only rebuid the modules from the IDE?

*EDIT*
Ok I did the new GDB-run, but the results were the same.
...back from Egypt

Midimaster

Quote from: iWasAdam on April 29, 2021, 10:59:14
...
thread 1 2 3 are all start_wqthread + 0
but from thread 4 it is a series of replicated threads with the following
Thread 4:
0   libsystem_kernel.dylib        0x00007fff2037cd4e __psynch_cvwait + 10
1   libsystem_pthread.dylib        0x00007fff203afea1 _pthread_cond_wait + 1298
2   PlayNoise.debug                0x0000000100952587 GC_wait_marker + 23 (pthread_support.c:2374)
3   PlayNoise.debug                0x0000000100949235 GC_help_marker + 37 (mark.c:1219)
4   PlayNoise.debug                0x0000000100950caf GC_mark_thread + 143 (pthread_support.c:414)
5   libsystem_pthread.dylib        0x00007fff203af954 _pthread_start + 224
6   libsystem_pthread.dylib        0x00007fff203ab4a7 thread_start + 15


this continues until thread 18 <- I would have thought only one thread would be needed?

thread 19 seems to be where the crash happens?
Thread 19 Crashed:: com.apple.audio.IOThread.client
0   PlayNoise.debug                0x000000010093aed7 bbThreadGetData + 23 (blitz_thread.c:83)
1   PlayNoise.debug                0x0000000100925bda brl_appstub_debugger_mt_stdio_GetDbgState + 122 (debugger_mt.stdio.bmx.debug.macos.x64.c:819)
2   PlayNoise.debug                0x0000000100928796 brl_appstub_debugger_mt_stdio_OnDebugEnterScope + 22 (debugger_mt.stdio.bmx.debug.macos.x64.c:1710)
3   PlayNoise.debug                0x00000001004fb3aa _m_PlayNoise_MyCallBack_II + 298 (PlayNoise.bmx.gui.debug.macos.x64.c:131)
4   PlayNoise.debug                0x0000000100556cda ma_device__on_data + 570 (miniaudio.h:11765)
<snip>




This might help?

P.S. there was not an error in the previous link code. But I was signalling that there 'could' be an error if you didn't release the malloc memory. This would be handled elsewhere, but is a potential if you don't know what is going on ;)

Im still struggling with this DEBUG crash of the wrapper and now I have again two questions related to your answer:

Your debugger points to a code line in miniaudio.h, but this line is a empty line. How can i interpret these line numbers in debuggers?

You told me there is a problem in this code.
// Call for the device
struct ma_device *MM_GetDevice(struct ma_device_config *config) {
printf("CREATE A DEVICE \n");
struct ma_device *instance;

int length = sizeof(struct ma_device);
instance = (struct ma_device*) malloc(length);
ma_device_init( NULL, config, instance);
return instance;
}

Can you tell me, what exactly I forgot? Can this be causal for the crash? (Think about I'm just starting with C)


How do you get this detailed informations when running debug mode? When I do it I get no additional informations.

...back from Egypt

col

QuoteYou told me there is a problem in this code.
instance = (struct ma_device*) malloc(length);

There is no problem with this piece of code. Where there will be a problem is IF (I've not looked through your code) you don't 'free' the instance via the pointer when you have finished with it. 'malloc' allocates the memory and 'free' will free the memory. If you don't free the memory and keep creating new instances then you will have a 'memory leak'. With a wrapper you can either call your freeing function directly (ideally as its deterministic) or drop it into a 'Delete' method of a Type so that it is called when the GC does its thing (not so ideal but still ok as its indeterminate as to when the GC will clean out the trash).


void MM_DestroyInstance(ma_device_config *config)
{
    free(config);
}

https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Midimaster

This function is only called once in the life of my app.

As you can see it returns the instance, because I need to store this "Device" (a STRUCT) for future handling:
Method StartDevice()
_StartDevice:Int (Device:Byte Ptr)
End Method

Method StopDevice()
_StopDevice:Int (Device:Byte Ptr)
End Method

Method KillDevice()
_KillDevice:Int (Device:Byte Ptr)
End Method


So I'm right when I say: "While the app in running this function cannot be the reason for crashes."

Another general question:
Can a "memory leak" become a problem and crash the computer after quitting my app? Or is it only like "a piece of RAM which is not avaiable any more until the computer restarts"?

...back from Egypt

col

Hiya.

I wasn't pointing out the cause of the crash, just what iWasAdam(?) was referring to.

Are you sure the math is correct in your callback? Just had a play and yes it runs ok in release but bombs out in debug. I would trust the bomb out in debug as opposed to things working correctly in release.

I would guess that your math is stomping on memory out of bounds of the banks that you're creating - Just a guess! but the error is typical of such a thing. The fact it runs ok in release is a red-herring and will bite you on your ass further down the line. Believe me... crashing is a good thing in this situation as you are being told that something is wrong.

https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Midimaster

#103
We are talking about a situation where already this crashs:
Code (BlitzMax) Select
Function MyCallBack(a%, Buffer:Short Ptr, RecordingBuffer:Short Ptr, Frames%)
' do something with the samples
End Function


whole code:
Code (BlitzMax) Select
SuperStrict

Import "MiniAudioWrapper.bmx"

Graphics 800,600

' Setup of the device:
Global MiniAudio:TMiniAudio=New TMiniAudio
If MiniAudio.GetDeviceConfig(MiniAudio.PLAYBACK)=False
Notify "Drive not startet"
EndIf
MiniAudio.SetDevice( Miniaudio.FORMAT_S16, 2, 48000, MyCallBack_II)


' now start it:
MiniAudio.StartDevice()
Repeat
Cls
DrawText "no need for doing anything",100,100
Flip 0
Until AppTerminate()
Miniaudio.KillDevice()
End


Function MyCallBack_II(a%, Buffer:Byte Ptr, RecordingBuffer:Short Ptr, Frames%)
' here you manipulate the sound:
Return
End Function
...back from Egypt

col

Yeah I've just rewrote the thing from scratch and it still crashes in the BMax callback - even an empty one. If you use a callback in the C code then all is ok...
still investigating as to why this is.
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."