ENV usage - OSS server

  • Follow


Dear Friends,

  Today I meet a problem on using ENV variable of OSS server -
I set env like below
ENV FIRSTNAME=WILLIAM
ENV LASTNAME=LIN
These 2 ENV are stored in heap (am not very sure, but I can see the
data after calling getenv() function), they are stored as below format
"FIRSTNAME=WILLIAM" ?0 "LASTNAME=LIN" ?0 ?0 ?0
so I can use env_firstname=getenv("FIRSTNAME") and
env_lastname=getenv("LASTNAME") to get their values.
This logic/code works good at the beginning start of server, the
program can get the values correctly. However, after running for a
while( about 10 mins later), the data in heap got changed - the word ?
0( between "WILLIAM" and "LASTNAME") got replaced with space. As a
result, the env_firstname became changed to be "WILLIAM LASTNAME=LIN"

I don't have the code that could change the value of env_firstname or
env_lastname, the only code may impact are strcat(destBuf,
env_firstname). It's quite possible the reason other than code.

Appreciate your advice.

Thanks
@will
0
Reply cdyjldy (59) 1/1/2011 6:21:27 PM

On Jan 1, 1:21=A0pm, "William, Lin" <cdyj...@msn.com> wrote:
> I don't have the code that could change the value of env_firstname or
> env_lastname, the only code may impact are strcat(destBuf,
> env_firstname). It's quite possible the reason other than code.

Very unlikely it is anything other than your code.
Env variables should always be referenced as const char * since the
variables are considered read only.
Without seeing the relevant snippets of code, it is impossible to
speculate on how the null byte was overwritten with a space.

You should be able to find it very easily with Inspect or Visual
Inspect.
After you have called getenv, set a memory access breakpoint on the
word containing the null byte.
Your program will stop at the point at which the null byte is
overwritten.
0
Reply warren7101 (47) 1/1/2011 7:15:34 PM


William, Lin wrote:
> Dear Friends,
> 
>   Today I meet a problem on using ENV variable of OSS server -
> I set env like below
> ENV FIRSTNAME=WILLIAM
> ENV LASTNAME=LIN
> These 2 ENV are stored in heap (am not very sure, but I can see the
> data after calling getenv() function), they are stored as below format
> "FIRSTNAME=WILLIAM" ?0 "LASTNAME=LIN" ?0 ?0 ?0
> so I can use env_firstname=getenv("FIRSTNAME") and
> env_lastname=getenv("LASTNAME") to get their values.
> This logic/code works good at the beginning start of server, the
> program can get the values correctly. However, after running for a
> while( about 10 mins later), the data in heap got changed - the word ?
> 0( between "WILLIAM" and "LASTNAME") got replaced with space. As a
> result, the env_firstname became changed to be "WILLIAM LASTNAME=LIN"
> 
> I don't have the code that could change the value of env_firstname or
> env_lastname, the only code may impact are strcat(destBuf,
> env_firstname). It's quite possible the reason other than code.
> 
> Appreciate your advice.
> 
> Thanks
> @will

One possibile cause for that is an incorrect pointer calculation somewhere in your code that causes some statement in your program to store a space character over the location where the environment variables are saved.  Another possible cause could be if you are modifying the environment using putenv().

I would try using a memory change breakpoint in the debugger to find the place in your code when that data is being changed.  Just after your program gets the pointer to "WILLIAM", try setting a memory change breakpoint on env_firstname+7.

If you are debugging with INSPECT, the command would be something like:

    BREAK env_firstname+7 CHANGE

If that syntax is not accepted or seems to put the breakpoint on the wrong address, try env_firstname[7], or display the value of the pointer using D env_firstname, add 7 to it yourself, and switch to low level INSPECT and set the breakpoint with the command:

    BM address,C

where address is the address you calculated.  

After you get the memory change breakpoint set, switch back to high level INSPECT and resume execution.  

When the data in the location given in the breakpoint is changed, your program will drop into INSPECT and you can use a TRACE command to see the call stack at that time, and if the program is executing in your code, you will be able to use all the other INSPECT commands to view the source code at that point and examine the values of the variables.  It should be pretty easy to see the immediate reason why the program is modifying that location of memory.  

Sometimes the immediate cause is that some data used in that part of the program has, itself, been improperly modified by using a bad pointer or subscript out of range.  In that case, you usually can employ the memory change breakpoint to find the cause of that improper access.

If you are using Native INSPECT on a TNS/E system, I am not sure how you can set the breakpoint using the symbolic name.  i think setting it using the address is clear, though I have never used it.  First display the value of the pointer:

    p /wx env_firstname

Then add 7 to that value and use the result to set the breakpoint:

    mab *0x00000000 1 -c

where you use the address you calculated in place of 000000000.

Then continue the program execution and wait for the program to drop into native inspect again when the change happens.  When the change happens, use the bt command to see the stack trace, and other debugger commands to view the source and look at values of your variables.

I do not know exactly how you set memory access breakpoints in Visual Inspect, but I imagine the online help will tell you how to do it.

Keep in mind that the location the system reports for the instruction that caused the data change might be slightly different than the instruction that actually is responsible, so look at nearby statements if the exact location indicated seems not to be the one that caused the change.

If you have trouble getting the memory change breakpoint to work, or if  the memory access breakpoint indicates a change is happening in a certain part of your program but cannot figure out how the code there could be making the change, post again with details about the trouble you are having and we will try to help.

   

0
Reply kdick (495) 1/1/2011 7:43:26 PM

William,

I am curious.  Environment values are inherited at the start of an
application.  I don't think there is any way to obtain the content of
any newly created or updated ENV variables, nor should there be a way
(you wouldn't want a running program to inherit an ENV value created
for another application later on).

That's why I wonder why your code keeps sampling ENV variables, long
after it started running?

0
Reply demoungu (305) 1/1/2011 8:50:24 PM

dimandja wrote:
> William,
> 
> I am curious.  Environment values are inherited at the start of an
> application.  I don't think there is any way to obtain the content of
> any newly created or updated ENV variables, nor should there be a way
> (you wouldn't want a running program to inherit an ENV value created
> for another application later on).
> 
> That's why I wonder why your code keeps sampling ENV variables, long
> after it started running?
> 

I'm not William, so I'm only guessing, but what he describes does not seem very unusual to me.

If I interpret it correctly, the program gets a pointer to the values of the environment variable values at some point probably early in the execution of the program.  Sometime later, when the program attempts to use the value pointed to by that pointer, it was wrong.  I imagine when he started debugging the problem, he found that the data pointed to was correct when the pointer was first obtained, but had changed by the time the program got around to using it.

I can imagine a couple of reasonable scenarios for calling getenv() repeatedly, but he isn't saying that is what this program did.
0
Reply kdick (495) 1/1/2011 11:26:17 PM

On Jan 1, 6:26=A0pm, Keith Dick <kd...@acm.org> wrote:
> dimandja wrote:
> > William,
>
> > I am curious. =A0Environment values are inherited at the start of an
> > application. =A0I don't think there is any way to obtain the content of
> > any newly created or updated ENV variables, nor should there be a way
> > (you wouldn't want a running program to inherit an ENV value created
> > for another application later on).
>
> > That's why I wonder why your code keeps sampling ENV variables, long
> > after it started running?
>
> I'm not William, so I'm only guessing, but what he describes does not see=
m very unusual to me.
>
> If I interpret it correctly, the program gets a pointer to the values of =
the environment variable values at some point probably early in the executi=
on of the program. =A0Sometime later, when the program attempts to use the =
value pointed to by that pointer, it was wrong. =A0I imagine when he starte=
d debugging the problem, he found that the data pointed to was correct when=
 the pointer was first obtained, but had changed by the time the program go=
t around to using it.
>
> I can imagine a couple of reasonable scenarios for calling getenv() repea=
tedly, but he isn't saying that is what this program did.



Actually, I find William's timing of this problem interesting.  He
says the problem seems to materialize "after running for a
while( about 10 mins later)".  I imagine his data pool to be corrupt
by then (as you mentioned earlier).

I'm still curious to know what his reasons were to sample those
variables 10 minutes later.  Why was it necessary?

Since this type of bug is usually logic driven, I think his answer to
this question could shed some light on the roots of the problem.
0
Reply demoungu (305) 1/1/2011 11:55:48 PM

dimandja wrote:
> On Jan 1, 6:26 pm, Keith Dick <kd...@acm.org> wrote:
> 
>>dimandja wrote:
>>
>>>William,
>>
>>>I am curious.  Environment values are inherited at the start of an
>>>application.  I don't think there is any way to obtain the content of
>>>any newly created or updated ENV variables, nor should there be a way
>>>(you wouldn't want a running program to inherit an ENV value created
>>>for another application later on).
>>
>>>That's why I wonder why your code keeps sampling ENV variables, long
>>>after it started running?
>>
>>I'm not William, so I'm only guessing, but what he describes does not seem very unusual to me.
>>
>>If I interpret it correctly, the program gets a pointer to the values of the environment variable values at some point probably early in the execution of the program.  Sometime later, when the program attempts to use the value pointed to by that pointer, it was wrong.  I imagine when he started debugging the problem, he found that the data pointed to was correct when the pointer was first obtained, but had changed by the time the program got around to using it.
>>
>>I can imagine a couple of reasonable scenarios for calling getenv() repeatedly, but he isn't saying that is what this program did.
> 
> 
> 
> 
> Actually, I find William's timing of this problem interesting.  He
> says the problem seems to materialize "after running for a
> while( about 10 mins later)".  I imagine his data pool to be corrupt
> by then (as you mentioned earlier).
> 
> I'm still curious to know what his reasons were to sample those
> variables 10 minutes later.  Why was it necessary?

We'll have to wait for William to answer to know for sure, but my guess is that the program is some kind of server program (he does title the post "OSS server" and the "ENV name=value" is Pathway syntax) and the typical mix of requests it gets does not include very many that reveal the problem.  So I imagine it usually takes around 10 minutes for the necessary history to develop that causes the problem.  

Another possibility is that the program is a batch processing program that takes 10 minutes to get to the point in the program where it needs to use those environment variables.  In that case, maybe "OSS server" in the title refers to the NonStop system -- do they refer to them as NonStop Servers?  I have to say I don't keep up with the marketing terms.  But I think this is not nearly as likely as the first guess I mentioned.

> 
> Since this type of bug is usually logic driven, I think his answer to
> this question could shed some light on the roots of the problem.
0
Reply kdick (495) 1/2/2011 12:57:31 AM

On Jan 1, 7:57=A0pm, Keith Dick <kd...@acm.org> wrote:
> dimandja wrote:
> > On Jan 1, 6:26 pm, Keith Dick <kd...@acm.org> wrote:
>
> >>dimandja wrote:
>
> >>>William,
>
> >>>I am curious. =A0Environment values are inherited at the start of an
> >>>application. =A0I don't think there is any way to obtain the content o=
f
> >>>any newly created or updated ENV variables, nor should there be a way
> >>>(you wouldn't want a running program to inherit an ENV value created
> >>>for another application later on).
>
> >>>That's why I wonder why your code keeps sampling ENV variables, long
> >>>after it started running?
>
> >>I'm not William, so I'm only guessing, but what he describes does not s=
eem very unusual to me.
>
> >>If I interpret it correctly, the program gets a pointer to the values o=
f the environment variable values at some point probably early in the execu=
tion of the program. =A0Sometime later, when the program attempts to use th=
e value pointed to by that pointer, it was wrong. =A0I imagine when he star=
ted debugging the problem, he found that the data pointed to was correct wh=
en the pointer was first obtained, but had changed by the time the program =
got around to using it.
>
> >>I can imagine a couple of reasonable scenarios for calling getenv() rep=
eatedly, but he isn't saying that is what this program did.
>
> > Actually, I find William's timing of this problem interesting. =A0He
> > says the problem seems to materialize "after running for a
> > while( about 10 mins later)". =A0I imagine his data pool to be corrupt
> > by then (as you mentioned earlier).
>
> > I'm still curious to know what his reasons were to sample those
> > variables 10 minutes later. =A0Why was it necessary?
>
> We'll have to wait for William to answer to know for sure, but my guess i=
s that the program is some kind of server program (he does title the post "=
OSS server" and the "ENV name=3Dvalue" is Pathway syntax) and the typical m=
ix of requests it gets does not include very many that reveal the problem. =
=A0So I imagine it usually takes around 10 minutes for the necessary histor=
y to develop that causes the problem. =A0
>
> Another possibility is that the program is a batch processing program tha=
t takes 10 minutes to get to the point in the program where it needs to use=
 those environment variables. =A0In that case, maybe "OSS server" in the ti=
tle refers to the NonStop system -- do they refer to them as NonStop Server=
s? =A0I have to say I don't keep up with the marketing terms. =A0But I thin=
k this is not nearly as likely as the first guess I mentioned.
>
>
>
>
>
> > Since this type of bug is usually logic driven, I think his answer to
> > this question could shed some light on the roots of the problem.- Hide =
quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -



I like your 2nd guess.  Batch programmes tend to scramble for Title
and Subtitle values toward the end of a run.
0
Reply demoungu (305) 1/2/2011 1:30:19 AM


Keith Dick wrote:
> William, Lin wrote:
> > Dear Friends,
> >
> >   Today I meet a problem on using ENV variable of OSS server -
> > I set env like below
> > ENV FIRSTNAME=3DWILLIAM
> > ENV LASTNAME=3DLIN
> > These 2 ENV are stored in heap (am not very sure, but I can see the
> > data after calling getenv() function), they are stored as below format
> > "FIRSTNAME=3DWILLIAM" ?0 "LASTNAME=3DLIN" ?0 ?0 ?0
> > so I can use env_firstname=3Dgetenv("FIRSTNAME") and
> > env_lastname=3Dgetenv("LASTNAME") to get their values.
> > This logic/code works good at the beginning start of server, the
> > program can get the values correctly. However, after running for a
> > while( about 10 mins later), the data in heap got changed - the word ?
> > 0( between "WILLIAM" and "LASTNAME") got replaced with space. As a
> > result, the env_firstname became changed to be "WILLIAM LASTNAME=3DLIN"
> >
> > I don't have the code that could change the value of env_firstname or
> > env_lastname, the only code may impact are strcat(destBuf,
> > env_firstname). It's quite possible the reason other than code.
> >
> > Appreciate your advice.
> >
> > Thanks
> > @will
>
> One possibile cause for that is an incorrect pointer calculation somewher=
e in your code that causes some statement in your program to store a space =
character over the location where the environment variables are saved.  Ano=
ther possible cause could be if you are modifying the environment using put=
env().
>
> I would try using a memory change breakpoint in the debugger to find the =
place in your code when that data is being changed.  Just after your progra=
m gets the pointer to "WILLIAM", try setting a memory change breakpoint on =
env_firstname+7.
>
> If you are debugging with INSPECT, the command would be something like:
>
>     BREAK env_firstname+7 CHANGE
>
> If that syntax is not accepted or seems to put the breakpoint on the wron=
g address, try env_firstname[7], or display the value of the pointer using =
D env_firstname, add 7 to it yourself, and switch to low level INSPECT and =
set the breakpoint with the command:
>
>     BM address,C
>
> where address is the address you calculated.
>
> After you get the memory change breakpoint set, switch back to high level=
 INSPECT and resume execution.
>
> When the data in the location given in the breakpoint is changed, your pr=
ogram will drop into INSPECT and you can use a TRACE command to see the cal=
l stack at that time, and if the program is executing in your code, you wil=
l be able to use all the other INSPECT commands to view the source code at =
that point and examine the values of the variables.  It should be pretty ea=
sy to see the immediate reason why the program is modifying that location o=
f memory.
>
> Sometimes the immediate cause is that some data used in that part of the =
program has, itself, been improperly modified by using a bad pointer or sub=
script out of range.  In that case, you usually can employ the memory chang=
e breakpoint to find the cause of that improper access.
>
> If you are using Native INSPECT on a TNS/E system, I am not sure how you =
can set the breakpoint using the symbolic name.  i think setting it using t=
he address is clear, though I have never used it.  First display the value =
of the pointer:
>
>     p /wx env_firstname
>
> Then add 7 to that value and use the result to set the breakpoint:
>
>     mab *0x00000000 1 -c
>
> where you use the address you calculated in place of 000000000.
>
> Then continue the program execution and wait for the program to drop into=
 native inspect again when the change happens.  When the change happens, us=
e the bt command to see the stack trace, and other debugger commands to vie=
w the source and look at values of your variables.
>
> I do not know exactly how you set memory access breakpoints in Visual Ins=
pect, but I imagine the online help will tell you how to do it.
>
> Keep in mind that the location the system reports for the instruction tha=
t caused the data change might be slightly different than the instruction t=
hat actually is responsible, so look at nearby statements if the exact loca=
tion indicated seems not to be the one that caused the change.
>
> If you have trouble getting the memory change breakpoint to work, or if  =
the memory access breakpoint indicates a change is happening in a certain p=
art of your program but cannot figure out how the code there could be makin=
g the change, post again with details about the trouble you are having and =
we will try to help.

Wow wonderful! I find out the root cause - yes, it's code issue.
Detail shown as below-
I tried the methods you mentioned above, it seems doesn't work
break *env_firstname change - doesnt work,it only catches the first
character "W"
break *env_firstname+6 change - doesn't work, invalid syntax
switch to low inspect - doen'st work, saying the program must be TNS

So what I did is add a new char * env_test =3D env_firm_nbr + 6;
break *env_test change   - this works

And I find the reason is that ?0 gets removed is the program has this
code
char adviceMsg[100];
adviceMsg[strlen(adviceMsg)]=3D ' '  and unfortunately I didn't specify
a \0 for adviceMsg. In this case it will replace all \0  one by one in
memory after this variable .

To answer other gentlemen's concerns about the usage /type of my
program -
It's a pathway server that processes thounds of request from other
programs. It will use the ENVs every time to format a out going
request to the services on other platform, that why I keep using these
ENVs during the whole processing.

At the end I want to say thank you, thank you ALL! You are amazing!

Thanks
@will
0
Reply cdyjldy (59) 1/4/2011 12:14:07 PM

William, Lin wrote:
> 
> Keith Dick wrote:
> 
>>William, Lin wrote:
>>
>>>Dear Friends,
>>>
>>>  Today I meet a problem on using ENV variable of OSS server -
>>>I set env like below
>>>ENV FIRSTNAME=WILLIAM
>>>ENV LASTNAME=LIN
>>>These 2 ENV are stored in heap (am not very sure, but I can see the
>>>data after calling getenv() function), they are stored as below format
>>>"FIRSTNAME=WILLIAM" ?0 "LASTNAME=LIN" ?0 ?0 ?0
>>>so I can use env_firstname=getenv("FIRSTNAME") and
>>>env_lastname=getenv("LASTNAME") to get their values.
>>>This logic/code works good at the beginning start of server, the
>>>program can get the values correctly. However, after running for a
>>>while( about 10 mins later), the data in heap got changed - the word ?
>>>0( between "WILLIAM" and "LASTNAME") got replaced with space. As a
>>>result, the env_firstname became changed to be "WILLIAM LASTNAME=LIN"
>>>
>>>I don't have the code that could change the value of env_firstname or
>>>env_lastname, the only code may impact are strcat(destBuf,
>>>env_firstname). It's quite possible the reason other than code.
>>>
>>>Appreciate your advice.
>>>
>>>Thanks
>>>@will
>>
>>One possibile cause for that is an incorrect pointer calculation somewhere in your code that causes some statement in your program to store a space character over the location where the environment variables are saved.  Another possible cause could be if you are modifying the environment using putenv().
>>
>>I would try using a memory change breakpoint in the debugger to find the place in your code when that data is being changed.  Just after your program gets the pointer to "WILLIAM", try setting a memory change breakpoint on env_firstname+7.
>>
>>If you are debugging with INSPECT, the command would be something like:
>>
>>    BREAK env_firstname+7 CHANGE
>>
>>If that syntax is not accepted or seems to put the breakpoint on the wrong address, try env_firstname[7], or display the value of the pointer using D env_firstname, add 7 to it yourself, and switch to low level INSPECT and set the breakpoint with the command:
>>
>>    BM address,C
>>
>>where address is the address you calculated.
>>
>>After you get the memory change breakpoint set, switch back to high level INSPECT and resume execution.
>>
>>When the data in the location given in the breakpoint is changed, your program will drop into INSPECT and you can use a TRACE command to see the call stack at that time, and if the program is executing in your code, you will be able to use all the other INSPECT commands to view the source code at that point and examine the values of the variables.  It should be pretty easy to see the immediate reason why the program is modifying that location of memory.
>>
>>Sometimes the immediate cause is that some data used in that part of the program has, itself, been improperly modified by using a bad pointer or subscript out of range.  In that case, you usually can employ the memory change breakpoint to find the cause of that improper access.
>>
>>If you are using Native INSPECT on a TNS/E system, I am not sure how you can set the breakpoint using the symbolic name.  i think setting it using the address is clear, though I have never used it.  First display the value of the pointer:
>>
>>    p /wx env_firstname
>>
>>Then add 7 to that value and use the result to set the breakpoint:
>>
>>    mab *0x00000000 1 -c
>>
>>where you use the address you calculated in place of 000000000.
>>
>>Then continue the program execution and wait for the program to drop into native inspect again when the change happens.  When the change happens, use the bt command to see the stack trace, and other debugger commands to view the source and look at values of your variables.
>>
>>I do not know exactly how you set memory access breakpoints in Visual Inspect, but I imagine the online help will tell you how to do it.
>>
>>Keep in mind that the location the system reports for the instruction that caused the data change might be slightly different than the instruction that actually is responsible, so look at nearby statements if the exact location indicated seems not to be the one that caused the change.
>>
>>If you have trouble getting the memory change breakpoint to work, or if  the memory access breakpoint indicates a change is happening in a certain part of your program but cannot figure out how the code there could be making the change, post again with details about the trouble you are having and we will try to help.
> 
> 
> Wow wonderful! I find out the root cause - yes, it's code issue.

I'm glad you found the problem.

> Detail shown as below-
> I tried the methods you mentioned above, it seems doesn't work
> break *env_firstname change - doesnt work,it only catches the first
> character "W"

Right, that will not catch the problem, and it was not among the commands I suggested.

> break *env_firstname+6 change - doesn't work, invalid syntax
> switch to low inspect - doen'st work, saying the program must be TNS

Maybe "break *(env_firstname+6) change" would have worked.  Or maybe *env_firstname[6].  Sorry that I cannot always give you the exact syntax that is accepted.  Anyway, your approach of declaring a pointer just to use to set the breakpoint is a good work around, but I am certain there is some way to set that breakpoint without changing the program's source code.

Sorry about wording it in a way that made it seem that you should use the LOW command.  For native, you have to use SELECT DEBUGGER DEBUG, and I never used it enough for that to sink in.  The difference is annoying.  I don't know why the developers don't just make LOW in a native-mode program do what SELECT DEBUGGER DEBUG does.  That would be much more helpful than just telling you that you can't do that.  Or at least LOW should tell you to use the SELECT DEBUGGER DEBUG command, although if it did that, I would then argue that if it can tell you what you should do, it ought to just *do* it.

> 
> So what I did is add a new char * env_test = env_firm_nbr + 6;
> break *env_test change   - this works

Yes, good work around for the problem of not knowing the right syntax for Inspect.

> 
> And I find the reason is that ?0 gets removed is the program has this
> code
> char adviceMsg[100];
> adviceMsg[strlen(adviceMsg)]= ' '  and unfortunately I didn't specify
> a \0 for adviceMsg. In this case it will replace all \0  one by one in
> memory after this variable .

Yes, cases where a null terminator is forgotten have caused many a problem in C programs, and some in TAL program, too.

> 
> To answer other gentlemen's concerns about the usage /type of my
> program -
> It's a pathway server that processes thounds of request from other
> programs. It will use the ENVs every time to format a out going
> request to the services on other platform, that why I keep using these
> ENVs during the whole processing.

That's a perfectly reasonable way for the program to work.

> 
> At the end I want to say thank you, thank you ALL! You are amazing!

You are welcome.  And thanks for following up to tell us how things were resolved.  Usually we never hear about the conclusion.

> 
> Thanks
> @will
0
Reply kdick (495) 1/4/2011 8:48:50 PM

9 Replies
30 Views

(page loaded in 0.243 seconds)


Reply: