🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
8 messages
8 total messages Started by Mike Collins Fri, 19 May 2006 12:35
Threads, PlaySound and waveOutGetNumDevs
#3593
Author: Mike Collins
Date: Fri, 19 May 2006 12:35
57 lines
3504 bytes
Hi all, i'm experiencing another very strange problem - hopefully someone 
will be able to point me in the right direction.  Basically I have a project 
that has several thread, one of which is used to poll and detect the 
presents of a USB token.  So it basically sits in a constant loop:

void __fastcall TKeyPollThread::Execute()
{
   SetName();
   while (!Terminated)
   {
      GetTokenData();
      Sleep(500);
   }
}

when the token is detected (within GetTokenData) I need to either play an 
audio file (33k embedded resource snippet) or play a double beep on the 
computers speaker.  If there is a sound card pressent, i'll play the audio 
file if not, i'll do a double beep.  I determine this by calling 
wavOutGetNumDevs like this...

           // GetTokenData....
            try                              //*
            {                                //*
               if (waveOutGetNumDevs() == 0)
               {
                  Beep(650, 150);
                  Beep(875, 150);
               }
               else
                  PlaySound("HW_INSERT_WAV_VIS", HInstance, 
SND_ASYNC|SND_RESOURCE);
            }      //*
            catch (...)                 //*
            {                              //*
               Beep(250, 5000); // *
            }                             //*

Now, what is really, really strange is this: I had to include the try... 
catch (indicated by //*) because the code was KILLING my thread.  In each 
execution of GetTokenData() i have a routine Beep so i can hear it polling. 
Now if i run this code / app on a machine that does NOT have a sound card I 
would hear the double beep then the thread would die, dead!  It didn't die 
on the waveOutGetNumDevs() because I could hear the double beeps but I 
didn't hear the Beep from within the catch, it just died.  Now, if I place 
the try..catch as I have shown above(//*), if works fine, I hear the double 
beep, no secondary beep from the catch and the thread does not die.

Does this make sense?  Does anyone have any ideas?  I know everyone will 
say, what is the catch statement returning (in terms of errors) but the 
simple answer is nothing - because I'm not getting that caught beep.  It 
just seems that by including the try catch i have somehow prevented the 
crashing of the thread whist still catching nothing.  What I'm basically 
saying is without the try.. catch the code kills the thread, with it in, it 
doesn't, BUT it doesn't catch anything either!

Thanks in advance, 
Re: Threads, PlaySound and waveOutGetNumDevs
#3597
Author: Remy Lebeau (TeamB)
Date: Fri, 19 May 2006 17:07
22 lines
1993 bytes
"Mike Collins" <its@TheBottomOfThePost.com> wrote in message
news:446dbb8d$1@newsgroups.borland.com...

> Does this make sense?  Does anyone have any ideas?  I know everyone will
> say, what is the catch statement returning (in terms of errors) but the
> simple answer is nothing - because I'm not getting that caught beep.  It
> just seems that by including the try catch i have somehow prevented the
> crashing of the thread whist still catching nothing.  What I'm basically
> saying is without the try.. catch the code kills the thread, with it in,
it
> doesn't, BUT it doesn't catch anything either!

Using a try..catch forces a stack frame to be created for the calling
function.  Without knowing what your thread is actually doing, my first
instinct is that you are probably corrupting the stack, and the try..catch
is hiding that since the stack is likely being restored to a proper state by
the stack frame when the function exits.  But that is just a guaess.  You
need to provide more details about your code in order to diangose it better.


Gambit
Re: Threads, PlaySound and waveOutGetNumDevs
#3598
Author: Mike Collins
Date: Fri, 19 May 2006 18:10
97 lines
4491 bytes
Thanks for the reply remy - I don't really know the inner workings of the 
try...catch / __finally systems. The GetTokenData simply communicates with a 
third party hardware token, namely rainbox iKeys.  It does very little but 
i've included the code below just for reference.  Obviously it's a bit more 
complicated once i've detected the hardware and read in it's data but the 
code below is a stripped down version that i'm testing and it still 
generates the same problems...

One things are appearent, the waveOutGetNumDevs() does not seem to be 
working as expected - on some of the testbeds that I have tried it does not 
report the existance of any soundcards when they are clearly there and 
present - i have tested this ourside the scope of this thread.

The iKey comms is pretty basic, open a handle, if the handle is valid, open 
a device based on that handle, read the data, close the device, close the 
handle...

void __fastcall TKeyPollThread::GeTokenData()
{
   IKEY_STATUS iStatus;
   IKEY_HANDLE iContextHandle;
   iStatus = ikey_CreateContext(&iContextHandle, 0, IKEY_API_VERSION);
   if (iStatus == RB_SUCCESS)
   {
      iStatus = ikey_OpenDevice(iContextHandle, IKEY_OPEN_FIRST, NULL);
      if (iStatus == RB_SUCCESS)
      {
         if (!strKeyData.bKeyPresent) <- local variable that indicates if 
the token was previously present...
         {
            // **** Problem code...
            try
            {
               if (waveOutGetNumDevs() == 0)
               {
                  Beep(650, 150);
                  Beep(875, 150);
               }
               else
                  PlaySound("HW_INSERT_WAV_VIS", HInstance, 
SND_ASYNC|SND_RESOURCE);
            }
            catch (...)
            {
               Beep(250, 5000);
            }
            // ***********
            strKeyData.bKeyPresent = true;
         }
         ikey_CloseDevice(iContextHandle);
      }
      else
      {
         if (strKeyData.bKeyPresent)
         {
            // The same would be true here but i haven't included the 
PlaySOund becuase of the problems...
            Beep(875, 150);
            Beep(650, 150);
            strKeyData.bKeyPresent = false;
         }
      }
      ikey_DeleteContext(iContextHandle);
   }
}




"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:446dfc10$1@newsgroups.borland.com...
>
> "Mike Collins" <its@TheBottomOfThePost.com> wrote in message
> news:446dbb8d$1@newsgroups.borland.com...
>
>> Does this make sense?  Does anyone have any ideas?  I know everyone will
>> say, what is the catch statement returning (in terms of errors) but the
>> simple answer is nothing - because I'm not getting that caught beep.  It
>> just seems that by including the try catch i have somehow prevented the
>> crashing of the thread whist still catching nothing.  What I'm basically
>> saying is without the try.. catch the code kills the thread, with it in,
> it
>> doesn't, BUT it doesn't catch anything either!
>
> Using a try..catch forces a stack frame to be created for the calling
> function.  Without knowing what your thread is actually doing, my first
> instinct is that you are probably corrupting the stack, and the try..catch
> is hiding that since the stack is likely being restored to a proper state 
> by
> the stack frame when the function exits.  But that is just a guaess.  You
> need to provide more details about your code in order to diangose it 
> better.
>
>
> Gambit
>
> 
Re: Threads, PlaySound and waveOutGetNumDevs
#3601
Author: Remy Lebeau (TeamB)
Date: Fri, 19 May 2006 18:45
21 lines
1880 bytes
"Mike Collins" <its@TheBottomOfThePost.com> wrote in message
news:446e0a32$1@newsgroups.borland.com...

> Thanks for the reply remy - I don't really know the inner workings of the
> try...catch / __finally systems. The GetTokenData simply communicates
> with a third party hardware token, namely rainbox iKeys.  It does very
little
> but i've included the code below just for reference.  Obviously it's a bit
more
> complicated once i've detected the hardware and read in it's data but the
> code below is a stripped down version that i'm testing and it still
> generates the same problems...

Then the only thing I can tell you to do is to rip out all of the code from
the thread and then start placing it back one line at a time, recompiling
and testing each time, until the problem starts again.  Then you will know
which line is responsible for causing the crash.


Gambit
Re: Threads, PlaySound and waveOutGetNumDevs
#3602
Author: Bob Gonder
Date: Fri, 19 May 2006 18:54
8 lines
1383 bytes
Mike Collins wrote:

>   iStatus = ikey_CreateContext(&iContextHandle, 0, IKEY_API_VERSION);

Are the ikey_ functions written as standard C functions?
Are they declared in the header as _stdcall (or worse, not specified)?
Mismatched calling conventions could cause stack corruption of the
type Remy suggests.
Re: Threads, PlaySound and waveOutGetNumDevs
#3604
Author: Mike Collins
Date: Sat, 20 May 2006 12:02
41 lines
2551 bytes
Thanks Bob, this could be an issue that is only manifesting it's self when I 
use the various functions that I have described.

In this particular implementation I'm dynamically loading the DLL and 
exported functions, instead of using the lib file.  The main dll is called 
iKeyAPI.dll and the header is iKeyAPI.h.  The general declaration of a 
function within the header is like this:

IKEY_STATUS IKEY_API ikey_CreateContext(
    IKEY_HANDLE   * PtrContextHandle,         // [out]
    unsigned long   Flags,                                      // [in]
    unsigned long   ApiVersion );                           // [in]

where IKEY_API is typedefed as __stdcall.  However there is also the #ifdef

#ifdef __cplusplus
extern "C" {
#endif

in my thead I create a typedef for each function and then use 
GetProcAddress, thus:

//TKeyPollThread.h...
typedef IKEY_STATUS IKEY_API (* T_ikey_CreateContext)(
                              IKEY_HANDLE *PtrContextHandle,      // [out]
                              unsigned long Flags,                // [in]
                              unsigned long ApiVersion);          // [in]
T_ikey_CreateContext  ikey_CreateContext;

//TKeyPollThread.cpp
ikey_CreateContext = (T_ikey_CreateContext)GetProcAddress(hKeyDLL, 
"ikey_CreateContext");




"Bob Gonder" <notbg@notmindspring.invalid> wrote in message 
news:uj4s62dv0f1o3dt7hdpj99rato13je2vvs@4ax.com...
> Mike Collins wrote:
>
> 
Re: Threads, PlaySound and waveOutGetNumDevs
#3606
Author: Bob Gonder
Date: Sat, 20 May 2006 14:40
20 lines
1895 bytes
Mike Collins wrote:

>Thanks Bob, this could be an issue that is only manifesting it's self when I 
>use the various functions that I have described.

Looks like it's time to dust off the debugger.
Set a breakpoint on the first line of the function.
Run.
View the CPU.
Note the value for esp and memorize the return address in the stack
window.
Now single step through the code, and pay attention to the stack
window and the esp.
If the esp changes after stepping over a call, then the called
function is buggy.
If you see the return address change, then the last item you stepped
on is buggy.
If you reach the return statement and esp isn't what it was when you
hit the breakpoint, then there's something wrong in your code, or a
compiler bug.
Re: Threads, PlaySound and waveOutGetNumDevs
#3609
Author: Mike Collins
Date: Sat, 20 May 2006 22:34
20 lines
1983 bytes
Bob, thanks again for the pointers and help, if very appreciated. 
Unfortunately this is a bit of a problematic development and I'm not able to 
debug it in the normal fashion (it's a GINA).

However, based on what you and Remy have both said, I stripped all the code 
that then re-built from the ground up.  I can't say 100% but the problem 
seems to have been rectified by excluding a debug routine that I had added 
that wrote to a debug text file.  For now the problem seems to be resolved.

Thanks again...

"Bob Gonder" <notbg@notmindspring.invalid> wrote in message 
news:eq9u62pf562ra979jh7squ9hk1j9n00uqm@4ax.com...
> Mike Collins wrote:
>
>>Thanks Bob, this could be an issue that is only manifesting it's self when 
>>I
>>use the various functions that I have described.
>
> Looks like it 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads