Weird memory issue with /clr, no problems without

  • Thread starter Thread starter Mesan
  • Start date Start date
M

Mesan

This is baffling me - I'm coming here in a desperate plea that someone
smarter than myself (which isn't hard) might be able to explain what's
going on.

I've got a native C++ console app that has been working perfectly -
built using VCExpress 2005, VC Redist, platform SDK (include
Windows.h, define WIN32_LEAN_AND_MEAN - am I missing anything?)

I recently found out how to "CLR enable" the app by 1) changing my new-
make file to compile with "/EHac /clr" instead of "/EHsc" and 2)
adding "#using <mscorlib.dll>; using namespace System;" to my code.

If I compile the program with all that C++/CLI stuff there's a weird
bug that shows up at runtime but not if I'm stepping through the
debugger - it's as if the debugger is giving extra time for statements
to complete, but I'm just pulling at straws there. There aren't any
threads in the program, so I'm not running into race conditions or
deadlocks within my own code, the problem looks like it's coming from
the environment.

Here's the behavior:
"run" the code in debugger w/no breakpoints: buggy.
"walk" the code in the debugger line by line: no problems.
"run" the code natively (outside the debugger): buggy.
Re-compile without all the C++/CLI stuff and run outside the debugger:
no problems.

What's going on? Is it a difference between the /EHsc (synchronous)
vs. /EHac (async) exception handling? There aren't any exceptions
being thrown - why would that make a difference?

I'm really stuck with this one - has anyone seen anything like this
before?

With tons of appreciation and thanks,

Mesan
 
Mesan said:
This is baffling me - I'm coming here in a desperate plea that someone
smarter than myself (which isn't hard) might be able to explain what's
going on.

I've got a native C++ console app that has been working perfectly -
built using VCExpress 2005, VC Redist, platform SDK (include
Windows.h, define WIN32_LEAN_AND_MEAN - am I missing anything?)

I recently found out how to "CLR enable" the app by 1) changing my new-
make file to compile with "/EHac /clr" instead of "/EHsc" and 2)
adding "#using <mscorlib.dll>; using namespace System;" to my code.

If I compile the program with all that C++/CLI stuff there's a weird
bug that shows up at runtime but not if I'm stepping through the
debugger - it's as if the debugger is giving extra time for statements
to complete, but I'm just pulling at straws there. There aren't any
threads in the program, so I'm not running into race conditions or
deadlocks within my own code, the problem looks like it's coming from
the environment.

Here's the behavior:
"run" the code in debugger w/no breakpoints: buggy.
"walk" the code in the debugger line by line: no problems.
"run" the code natively (outside the debugger): buggy.
Re-compile without all the C++/CLI stuff and run outside the debugger:
no problems.


What is the buggy behavior?

What's going on? Is it a difference between the /EHsc (synchronous)
vs. /EHac (async) exception handling? There aren't any exceptions
being thrown - why would that make a difference?


From the docs:
"/clr implies /EHa, and no other /EH options are allowed with /clr."


Maybe try creating a managed console app with the wizard. Then compare the
compiler/linker settings to the settings in your makefile ...any
differences?

Mark
 
FWIW - here's the default command lines for a wizard-generated CLR console
project...

Compiler:

/Od /D "WIN32" /D "_DEBUG" /D "_UNICODE" /D "UNICODE"
/FD /EHa /MDd /Yu"stdafx.h" /Fp"Debug\TestCLRConsole.pch"
/Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /Zi /clr
/TP /errorReport:prompt
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll"


Linker:

/OUT:"E:\Source_LabCDM\Debug\TestCLRConsole.exe" /INCREMENTAL
/NOLOGO /MANIFEST
/MANIFESTFILE:"Debug\TestCLRConsole.exe.intermediate.manifest"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/DEBUG /ASSEMBLYDEBUG /PDB:"e:\Source_LabCDM\Debug\TestCLRConsole.pdb"
/DYNAMICBASE /FIXED:No /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT


Mark
 
FWIW - here's the default command lines for a wizard-generated CLR console
project...

Compiler:

/Od /D "WIN32" /D "_DEBUG" /D "_UNICODE" /D "UNICODE"
/FD /EHa /MDd /Yu"stdafx.h" /Fp"Debug\TestCLRConsole.pch"
/Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /Zi /clr
/TP /errorReport:prompt
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll"

Linker:

/OUT:"E:\Source_LabCDM\Debug\TestCLRConsole.exe" /INCREMENTAL
/NOLOGO /MANIFEST
/MANIFESTFILE:"Debug\TestCLRConsole.exe.intermediate.manifest"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/DEBUG /ASSEMBLYDEBUG /PDB:"e:\Source_LabCDM\Debug\TestCLRConsole.pdb"
/DYNAMICBASE /FIXED:No /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT

Mark

Wow - I am so thankful to both of you for your responses. I'm in the
process of trying them - no luck yet, but I haven't tried anything yet
either. I just wanted to post back and say thank you.

Wish me luck!

Mesan
 
Wow - I am so thankful to both of you for your responses.  I'm in the
process of trying them - no luck yet, but I haven't tried anything yet
either.  I just wanted to post back and say thank you.

Wish me luck!

Mesan- Hide quoted text -

- Show quoted text -

Alright, I've found the line of code that's giving me my problems, but
I fear I'm no closer to a solution.
Here's the code in question, including logging statements that I added
since the debugger was changing the program's behavior:


1: Logger::Write("Starting to check MOS");
2: temp_led->data.mos=atoi(temp);
3: Logger::Write("temp_led->data.mos="+temp_led->data.mos);
4: return_value=check_months(&(temp_led->data), temp_hist-
data.acct/10000,
5: &address_of_1, 0, 8, 20, temp_hist-
data.name+2);
6: Logger::Write("return_value="+return_value);

When the code runs as written, everything works. When I comment out
line 3, the bug shows up. It's as if line 2 doesn't commit its change
to memory before line 4 runs.

Is there a problem with my code? Am I doing something wrong? I don't
want to just access temp_led->data.mos and use that as my solution,
because that's just a band-aid - that might take care of this
occurance for now, but I wouldn't have solved the underlying
problem.

Is it possible the program is running in more than 1 thread/
processor? If that's the case, is there a way I can force the program
to only run on one thread? I need async exception handling in order
to use .Net though, so I have to keep the /EHa.

Here's my full compile and link statements, if that helps. I tried
all the other options that you suggested and none of them made a
difference.

cl -Zi -Od -c /LD /MD /EHa /clr -W2 -DWIN32 -Foc:myprog.obj myprog.cxx
link -debug -out:myprog.exe myprog.obj c:\source\win32\libX
\utilemb.obj db2api.lib kernel32.lib /NODEFAULTLIB:LIBCMT

____________________

On a slightly more humerous note, I told a co-worker that I had
successfully made a quantum computer. The big thing about quantum
computers is that if you observe their state, their state changes -
right? Well, when you observe this variable's state, it changes.
Doesn't that qualify this program as "quantum"? :-)
 
Alright, I've found the line of code that's giving me my problems, but
I fear I'm no closer to a solution.
Here's the code in question, including logging statements that I added
since the debugger was changing the program's behavior:


1: Logger::Write("Starting to check MOS");
2: temp_led->data.mos=atoi(temp);
3: Logger::Write("temp_led->data.mos="+temp_led->data.mos);
4: return_value=check_months(&(temp_led->data), temp_hist-
5: &address_of_1, 0, 8, 20, temp_hist-
6: Logger::Write("return_value="+return_value);


There's not enough info there for me to debug.

What is temp_led?
What is the value of temp at the call to atio()?
What is check_months?
What is address_of_1 and why are you passing its address?
What is the magic number "+2" doing?

There's no other threads involved unless you create them (or call something
that creates them).

Mark
 
Alright, I've found the line of code that's giving me my problems, but
I fear I'm no closer to a solution.
Here's the code in question, including logging statements that I added
since the debugger was changing the program's behavior:

1:     Logger::Write("Starting to check MOS");
2:     temp_led->data.mos=atoi(temp);
3:     Logger::Write("temp_led->data.mos="+temp_led->data.mos);
4:     return_value=check_months(&(temp_led->data), temp_hist->data..acct/10000,

5:                                 &address_of_1, 0, 8, 20, temp_hist->data.name+2);

6:     Logger::Write("return_value="+return_value);

When the code runs as written, everything works.  When I comment out
line 3, the bug shows up.  It's as if line 2 doesn't commit its change
to memory before line 4 runs.

Is there a problem with my code?  Am I doing something wrong?  I don't
want to just access temp_led->data.mos and use that as my solution,
because that's just a band-aid - that might take care of this
occurance for now, but I wouldn't have solved the underlying
problem.

Is it possible the program is running in more than 1 thread/
processor?  If that's the case, is there a way I can force the program
to only run on one thread?  I need async exception handling in order
to use .Net though, so I have to keep the /EHa.

Here's my full compile and link statements, if that helps.  I tried
all the other options that you suggested and none of them made a
difference.

cl -Zi -Od -c /LD /MD /EHa /clr -W2 -DWIN32 -Foc:myprog.obj myprog.cxx
link -debug -out:myprog.exe myprog.obj c:\source\win32\libX
\utilemb.obj db2api.lib kernel32.lib /NODEFAULTLIB:LIBCMT

____________________

On a slightly more humerous note, I told a co-worker that I had
successfully made a quantum computer.  The big thing about quantum
computers is that if you observe their state, their state changes -
right?  Well, when you observe this variable's state, it changes.
Doesn't that qualify this program as "quantum"? :-)- Hide quoted text -

- Show quoted text -

I replaced the atoi() call with System::Convert::ToInt32() and that
seems to have fixed it.
Is that a bad solution? It still seems kind of like voodoo to me, I
wish I had a better handle on exactly what caused the issue.

Any ideas?
 
Mesan said:
I replaced the atoi() call with System::Convert::ToInt32() and that
seems to have fixed it.
Is that a bad solution? It still seems kind of like voodoo to me, I
wish I had a better handle on exactly what caused the issue.


There's nothing wrong with the fix, but again, there wasn't enough info for
me to determine what was going wrong with your call to atoi().


Mark
 
There's not enough info there for me to debug.

What is temp_led?
What is the value of temp at the call to atio()?
What is check_months?
What is address_of_1 and why are you passing its address?
What is the magic number "+2" doing?

There's no other threads involved unless you create them (or call something
that creates them).

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++








- Show quoted text -


temp_led is defined as LED_LIST_type *

LED_LIST_type is defined as:

typedef struct def_LED {
long trans;
int line;
long acct;
long postdt;
long effdte;
char ref[3];
long amt;
char check[8];
char aslkey[7];
char name[67];
char descr[67];
char code[7];
int mos;
char imp[4];
char userid[4];
long rtrndt;
short
Fcheck,Faslkey,Fname,Fdescr,Fcode,Fmos,Fimp,Frtrndt,Fuserid;
} LED_type;
typedef struct def_LED_LIST {
LED_type data;
struct def_LED_LIST *prior, *next;
} LED_LIST_type;

When atoi() is called, temp is a char[] with the contents "1".
check_months() is a validation function.
address_of_1 is an int, initialized to 1. The check_months() function
wants a pointer to a counter, but in this case I only want to send a
1, I couldn't say &1, so I used &address_of_1.
The magic +2 gets you to the actual string data. When you send
variable length strings back and forth to a DB2 database, the data
comes with the first two bytes as the length of the string, the
remainder is the string data. It's often used as a struct{} with a
short and a char[], but this company commonly used "(short)variable"
to get the length and "variable+2" to access the string data.

I don't have any other threads in the program, the only thing I can
think of is the MS implementation goo behind the scenes that hooks up
the .Net app domain with this native code.

Does this information give sufficient context to the code?

Thanks for not giving up on this - I can't help but feel like my use
of Convert::ToInt32() is just makeup - it looks better, but the
underlying problem is still lurking, waiting to catch me with other C+
+/CLI code when I least expect it.
 
Mesan said:
temp_led is defined as LED_LIST_type *

LED_LIST_type is defined as:

typedef struct def_LED {
long trans;
int line;
long acct;
long postdt;
long effdte;
char ref[3];
long amt;
char check[8];
char aslkey[7];
char name[67];
char descr[67];
char code[7];
int mos;
char imp[4];
char userid[4];
long rtrndt;
short
Fcheck,Faslkey,Fname,Fdescr,Fcode,Fmos,Fimp,Frtrndt,Fuserid;
} LED_type;
typedef struct def_LED_LIST {
LED_type data;
struct def_LED_LIST *prior, *next;
} LED_LIST_type;

When atoi() is called, temp is a char[] with the contents "1".
check_months() is a validation function.
address_of_1 is an int, initialized to 1. The check_months() function
wants a pointer to a counter, but in this case I only want to send a
1, I couldn't say &1, so I used &address_of_1.
The magic +2 gets you to the actual string data. When you send
variable length strings back and forth to a DB2 database, the data
comes with the first two bytes as the length of the string, the
remainder is the string data. It's often used as a struct{} with a
short and a char[], but this company commonly used "(short)variable"
to get the length and "variable+2" to access the string data.

I don't have any other threads in the program, the only thing I can
think of is the MS implementation goo behind the scenes that hooks up
the .Net app domain with this native code.

Does this information give sufficient context to the code?


Excellent - thanks for the details!

I don't see anything that should be a problem.

Uninitialized or invalid variable (pointer!) maybe being used somewhere and
it just happens to work...?

If I think of something I'll let you know!

Mark
 
temp_led is defined as LED_LIST_type *
LED_LIST_type is defined as:
  typedef struct def_LED {
      long  trans;
      int   line;
      long  acct;
      long  postdt;
      long  effdte;
      char ref[3];
      long  amt;
      char check[8];
      char aslkey[7];
      char name[67];
      char descr[67];
      char code[7];
      int   mos;
      char imp[4];
      char userid[4];
      long  rtrndt;
      short
Fcheck,Faslkey,Fname,Fdescr,Fcode,Fmos,Fimp,Frtrndt,Fuserid;
      } LED_type;
  typedef struct def_LED_LIST {
     LED_type data;
     struct def_LED_LIST *prior, *next;
     } LED_LIST_type;
When atoi() is called, temp is a char[] with the contents "1".
check_months() is a validation function.
address_of_1 is an int, initialized to 1.  The check_months() function
wants a pointer to a counter, but in this case I only want to send a
1, I couldn't say &1, so I used &address_of_1.
The magic +2 gets you to the actual string data.  When you send
variable length strings back and forth to a DB2 database, the data
comes with the first two bytes as the length of the string, the
remainder is the string data.  It's often used as a struct{} with a
short and a char[], but this company commonly used "(short)variable"
to get the length and "variable+2" to access the string data.
I don't have any other threads in the program, the only thing I can
think of is the MS implementation goo behind the scenes that hooks up
the .Net app domain with this native code.
Does this information give sufficient context to the code?

Excellent - thanks for the details!

I don't see anything that should be a problem.

Uninitialized or invalid variable (pointer!) maybe being used somewhere and
it just happens to work...?

If I think of something I'll let you know!

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++




Thanks for not giving up on this - I can't help but feel like my use
of Convert::ToInt32() is just makeup - it looks better, but the
underlying problem is still lurking, waiting to catch me with other C+
+/CLI code when I least expect it.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Mark - Any ideas come to mind?

Just curious.
 
Hi,

Found a good answer yet?

I have a very similar problem, and I found a solution: "/
ASSEMBLYDEBUG" (linker switch)

This enables runtime-tracking and disables JIT optimizations.

I __suspect__ the problem lies somewhere in the JIT optimizations -
but after two days of debugging, I still can't say for sure if that is
the case or not.

All I know is that after flipping all the switches that were different
between "debug" and "release" mode, this is the one that did the
trick. Now I've left everything else in standard "release" settings,
but changed this item. [Granted, with runtime debugging no JIT
optimizations, all the other switches may get washed away anyway.]

Be aware that the .Net Garbage Collector runs in a separate thread.
(supposedly you can turn this off with 'gcConcurrent' -
http://msdn.microsoft.com/en-us/library/yhwwzef8.aspx ). But there's
advantages to letting it run concurrently. Whether enough to justify
disabling JIT optimizations, I don't know; but I have a multi-threaded
program anyway, so it's not immediately relevant to me.

(I'm creating a .Net wrapper for a native C library. I have all of
one variable to initialize, and it only happens in a few places in one
file. There's slim chance of it not getting initialized, especially
after two days of me poring over the 8 places it could be. But it
could still be the _way_ I'm initializing things. Who knows...)

Good luck. And if you've found any other solutions, I'd love to hear
them.


Ciao!
Bibek
 
There's not enough info there for me to debug.
What is temp_led?
What is the value of temp at the call to atio()?
What is check_months?
What is address_of_1 and why are you passing its address?
What is the magic number "+2" doing?
There's no other threads involved unless you create them (or call something
that creates them).
- Show quoted text -

temp_led is defined as LED_LIST_type *

LED_LIST_type is defined as:

   typedef struct def_LED {
       long  trans;
       int   line;
       long  acct;
       long  postdt;
       long  effdte;
       char ref[3];
       long  amt;
       char check[8];
       char aslkey[7];
       char name[67];
       char descr[67];
       char code[7];
       int   mos;
       char imp[4];
       char userid[4];
       long  rtrndt;
       short
Fcheck,Faslkey,Fname,Fdescr,Fcode,Fmos,Fimp,Frtrndt,Fuserid;
       } LED_type;
   typedef struct def_LED_LIST {
      LED_type data;
      struct def_LED_LIST *prior, *next;
      } LED_LIST_type;

When atoi() is called, temp is a char[] with the contents "1".
check_months() is a validation function.
address_of_1 is an int, initialized to 1.  The check_months() function
wants a pointer to a counter, but in this case I only want to send a
1, I couldn't say &1, so I used &address_of_1.
The magic +2 gets you to the actual string data.  When you send
variable length strings back and forth to a DB2 database, the data
comes with the first two bytes as the length of the string, the
remainder is the string data.  It's often used as a struct{} with a
short and a char[], but this company commonly used "(short)variable"
to get the length and "variable+2" to access the string data.

I don't have any other threads in the program, the only thing I can
think of is the MS implementation goo behind the scenes that hooks up
the .Net app domain with this native code.

Does this information give sufficient context to the code?

Thanks for not giving up on this - I can't help but feel like my use
of Convert::ToInt32() is just makeup - it looks better, but the
underlying problem is still lurking, waiting to catch me with other C+
+/CLI code when I least expect it.

It's interesting that your code crashes at 'atoi()', but works with
System::Convert::ToInt32().

The work I'm doing is wrapping GMP (a big-number math library)
for .Net.

Also, "BigInteger" was scheduled to be released with .Net 3.5, but was
pulled at the last minute by Microsoft.

With all these math-related issues, it makes me wonder if there's some
re-entrace problem (e.g., global variable?) in the math library
functions in the standard C / MFC library, which is not an issue in
debug mode but is in normal mode. I do know that some old C-library
math functions used static global variables in places (on some unix,
and I think DOS too); I don't know about now.

- Bibek
 
temp_led is defined as LED_LIST_type *
LED_LIST_type is defined as:
   typedef struct def_LED {
       long  trans;
       int   line;
       long  acct;
       long  postdt;
       long  effdte;
       char ref[3];
       long  amt;
       char check[8];
       char aslkey[7];
       char name[67];
       char descr[67];
       char code[7];
       int   mos;
       char imp[4];
       char userid[4];
       long  rtrndt;
       short
Fcheck,Faslkey,Fname,Fdescr,Fcode,Fmos,Fimp,Frtrndt,Fuserid;
       } LED_type;
   typedef struct def_LED_LIST {
      LED_type data;
      struct def_LED_LIST *prior, *next;
      } LED_LIST_type;
When atoi() is called, temp is a char[] with the contents "1".
check_months() is a validation function.
address_of_1 is an int, initialized to 1.  The check_months() function
wants a pointer to a counter, but in this case I only want to send a
1, I couldn't say &1, so I used &address_of_1.
The magic +2 gets you to the actual string data.  When you send
variable length strings back and forth to a DB2 database, the data
comes with the first two bytes as the length of the string, the
remainder is the string data.  It's often used as a struct{} with a
short and a char[], but this company commonly used "(short)variable"
to get the length and "variable+2" to access the string data.
I don't have any other threads in the program, the only thing I can
think of is the MS implementation goo behind the scenes that hooks up
the .Net app domain with this native code.
Does this information give sufficient context to the code?
Thanks for not giving up on this - I can't help but feel like my use
of Convert::ToInt32() is just makeup - it looks better, but the
underlying problem is still lurking, waiting to catch me with other C+
+/CLI code when I least expect it.

It's interesting that your code crashes at 'atoi()', but works with
System::Convert::ToInt32().

The work I'm doing is wrapping GMP (a big-number math library)
for .Net.

Also, "BigInteger" was scheduled to be released with .Net 3.5, but was
pulled at the last minute by Microsoft.

With all these math-related issues, it makes me wonder if there's some
re-entrace problem (e.g., global variable?) in the math library
functions in the standard C / MFC library, which is not an issue in
debug mode but is in normal mode.  I do know that some old C-library
math functions used static global variables in places (on some unix,
and I think DOS too); I don't know about now.

- Bibek

Well, I can't speak for the other math issues.

But in my case, GC::KeepAlive() fixed it. Apparently the optimizer
thought some of my stuff was fair game before it was fair game.

- Bibek
 
On Aug 7, 9:10 am, "Mark Salsbery [MVP]"
Alright, I've found the line of code that's giving me my problems, but
I fear I'm no closer to a solution.
Here's the code in question, including logging statements that I added
since the debugger was changing the program's behavior:
1:     Logger::Write("Starting to check MOS");
2:     temp_led->data.mos=atoi(temp);
3:     Logger::Write("temp_led->data.mos="+temp_led->data.mos);
4:     return_value=check_months(&(temp_led->data), temp_hist-
data.acct/10000,
5:                                 &address_of_1, 0, 8, 20, temp_hist-
data.name+2);
6:     Logger::Write("return_value="+return_value);
There's not enough info there for me to debug.
What is temp_led?
What is the value of temp at the call to atio()?
What is check_months?
What is address_of_1 and why are you passing its address?
What is the magic number "+2" doing?
There's no other threads involved unless you create them (or call something
that creates them).
Mark
--
Mark Salsbery
Microsoft MVP - Visual C++
When the code runs as written, everything works.  When I comment out
line 3, the bug shows up.  It's as if line 2 doesn't commit itschange
to memory before line 4 runs.
Is there a problem with my code?  Am I doing something wrong?  I don't
want to just access temp_led->data.mos and use that as my solution,
because that's just a band-aid - that might take care of this
occurance for now, but I wouldn't have solved the underlying
problem.
Is it possible the program is running in more than 1 thread/
processor?  If that's the case, is there a way I can force the program
to only run on one thread?  I need async exception handling in order
to use .Net though, so I have to keep the /EHa.
Here's my full compile and link statements, if that helps.  I tried
all the other options that you suggested and none of them made a
difference.
cl -Zi -Od -c /LD /MD /EHa /clr -W2 -DWIN32 -Foc:myprog.obj myprog.cxx
link -debug -out:myprog.exe myprog.obj c:\source\win32\libX
\utilemb.obj db2api.lib kernel32.lib /NODEFAULTLIB:LIBCMT
____________________
On a slightly more humerous note, I told a co-worker that I had
successfully made a quantum computer.  The big thing about quantum
computers is that if you observe their state, their state changes-
right?  Well, when you observe this variable's state, it changes.
Doesn't that qualify this program as "quantum"? :-)- Hide quoted text -
- Show quoted text -
temp_led is defined as LED_LIST_type *
LED_LIST_type is defined as:
   typedef struct def_LED {
       long  trans;
       int   line;
       long  acct;
       long  postdt;
       long  effdte;
       char ref[3];
       long  amt;
       char check[8];
       char aslkey[7];
       char name[67];
       char descr[67];
       char code[7];
       int   mos;
       char imp[4];
       char userid[4];
       long  rtrndt;
       short
Fcheck,Faslkey,Fname,Fdescr,Fcode,Fmos,Fimp,Frtrndt,Fuserid;
       } LED_type;
   typedef struct def_LED_LIST {
      LED_type data;
      struct def_LED_LIST *prior, *next;
      } LED_LIST_type;
When atoi() is called, temp is a char[] with the contents "1".
check_months() is a validation function.
address_of_1 is an int, initialized to 1.  The check_months() function
wants a pointer to a counter, but in this case I only want to send a
1, I couldn't say &1, so I used &address_of_1.
The magic +2 gets you to the actual string data.  When you send
variable length strings back and forth to a DB2 database, the data
comes with the first two bytes as the length of the string, the
remainder is the string data.  It's often used as a struct{} with a
short and a char[], but this company commonly used "(short)variable"
to get the length and "variable+2" to access the string data.
I don't have any other threads in the program, the only thing I can
think of is the MS implementation goo behind the scenes that hooks up
the .Net app domain with this native code.
Does this information give sufficient context to the code?
Thanks for not giving up on this - I can't help but feel like my use
of Convert::ToInt32() is just makeup - it looks better, but the
underlying problem is still lurking, waiting to catch me with other C+
+/CLI code when I least expect it.
It's interesting that your code crashes at 'atoi()', but works with
System::Convert::ToInt32().
The work I'm doing is wrapping GMP (a big-number math library)
for .Net.
Also, "BigInteger" was scheduled to be released with .Net 3.5, but was
pulled at the last minute by Microsoft.
With all these math-related issues, it makes me wonder if there's some
re-entrace problem (e.g., global variable?) in the math library
functions in the standard C / MFC library, which is not an issue in
debug mode but is in normal mode.  I do know that some old C-library
math functions used static global variables in places (on some unix,
and I think DOS too); I don't know about now.

Well, I can't speak for the other math issues.

But in my case, GC::KeepAlive() fixed it.  Apparently the optimizer
thought some of my stuff was fair game before it was fair game.

- Bibek- Hide quoted text -

- Show quoted text -

Good to hear you've got it to work. It turned out for my case that I
was incorrectly building DLLs, so once I built them correctly
everything started to work.

Take care,
Mesan
 
Back
Top