LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-12-2009, 08:12 AM   #16
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197

Quote:
Originally Posted by dayalan_cse View Post
Do you mean, the new value of 32-63 bits will have by default high as binary value 1 so it becomes 0x ff ff ff ff <0-31 old value> ?
No.

If the old value was 0x0000000 through 0x7FFFFFFF the new value will be 0x00000000<0-31 old value> but if the old value was 0x80000000 through 0xFFFFFFFF the new value will be 0xFFFFFFFF<0-31 old value>

When I used the word "high" in my previous attempt to explain, I meant high bit positions within the 32 or 64 bit integer, not the high bit value (1).
 
Old 02-10-2012, 07:46 AM   #17
akshay_satish
Member
 
Registered: May 2011
Posts: 63

Rep: Reputation: Disabled
Help with a simlar question

I was going through this thread and I thought my problem/question is similar to this one..

0x00007ffff3e98f09 <func_instance+345>: jo 0x7ffff3e98f0f <func_instance+351>
0x00007ffff3e98f0b <func_instance+347>: mov 0x10(%rsp),%rdi
0x00007ffff3e98f10 <func_instance+352>: callq 0x7ffff3e1a1f8 <func_instance@plt>
0x00007ffff3e98f15 <func_instance+357>: mov 0x8(%rsp),%rdx
0x00007ffff3e98f1a <func_instance+362>: mov %rax,%rsi
0x00007ffff3e98f1d <func_instance+365>: movzbl 0x4f(%rax),%eax
0x00007ffff3e98f21 <func_instance+369>: cmp 0x4f(%rdx),%al
0x00007ffff3e98f24 <func_instance+372>: je 0x7ffff3e98fa0 <func_instance+496>
0x00007ffff3e98f26 <func_instancej+374>: mov (%r12),%eax
End of assembler dump.

I am hitting a SIGSEGV(NULL pointer dereference) on the below instruction:

<TAG>
0x00007ffff3e98f1d <func_instance+365>: movzbl 0x4f(%rax),%eax
</TAG>

Can anyone elaborate a little more on these instructions. I have a very basic understanding though. Platform is an ia64

Last edited by akshay_satish; 02-10-2012 at 07:47 AM.
 
Old 02-10-2012, 08:27 AM   #18
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,642
Blog Entries: 4

Rep: Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933
What they're talking about is sign extending. (Maybe that's not the correct term but I think you get what I mean.)

If the quantity that you are dealing with is assumed to be a 32-bit signed quantity, then the most-significant bit (MSB) is a sign-bit and the number is in so-called two's complement notation. The quantity "-1" is $FFFFFFFF, in the customary hexadecimal.

If you load this 32-bit signed quantity into a 64-bit accumulator, the leftmost bit (the sign-bit) is extended into all of the unoccupied slots, since the 64-bit version of "-1" is of course $FFFFFFFFFFFFFFFF, thus correctly preserving its two's-complement representation.

Now, what if you, the almighty programmer, assert that the value is, in fact, unsigned? (Obviously, it's impossible to tell one from the other by looking at the bits...) In this case, $FFFFFFFF is the decimal quantity 4,294,967,296 and the proper way to load it into a 64-bit register produces $00000000FFFFFFFF.

Certainly, one of the "gotchas" of 64-bithood is that int is signed, and that it is also carelessly used as being "synonymous with a pointer," which in this case is no longer true. If you assumed a 32-bit world, then you could simply handle these quantities with impunity ... just ignore the MSB when you wanted to. But, now, sign-extending is occurring rather constantly if the word-size of the data you're dealing with is still 32-bits but now your CPU speaks 64. Suddenly, all of the leftmost-bits of your derived address (as many as your hardware actually cares about ...) have transmogrified themselves into 1's, and you are not looking anywhere near the right place in memory anymore. C'est la guerre...

Last edited by sundialsvcs; 02-10-2012 at 08:32 AM.
 
Old 02-10-2012, 08:51 AM   #19
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by akshay_satish View Post
I was going through this thread and I thought my problem/question is similar to this one..
Doesn't look similar to me. I think sundialsvcs answered on the original topic, so that doesn't help you. That's one of the risks of reopening an old thread for a new question.

Quote:
0x00007ffff3e98f10 <func_instance+352>: callq 0x7ffff3e1a1f8 <func_instance@plt>
It would be helpful to know the declaration of the function that was compiled/loaded as func_instance@plt
Based on the subsequent code, I expect that function was declared as returning a pointer to some struct type but when called, it returned a zero (NULL pointer). In x86_64 pointers are returned from functions in %rax
Code:
0x00007ffff3e98f1d <func_instance+365>:     movzbl 0x4f(%rax),%eax
That takes the character 79 beyond what is pointed to by %rax and moves it into %al (which is the low byte of %rax) and clears the remainder of %rax.
But you are reporting that it instead causes a NULL pointer dereference, so I assume %rax had zero in it before executing that instruction.
Quote:
Platform is an ia64
No. It is x86_64. IA64 is a different Intel 64 bit architecture.
Quote:
elaborate a little more on these instructions.
Code:
jo 0x7ffff3e98f0f <func_instance+351>
Garbage (incorrect disassembly) caused by starting to disassemble at an address that wasn't an instruction boundary.
Code:
mov 0x10(%rsp),%rdi
Move a 64 bit quantity, probably from a local variable, into the register used to pass the first parameter to a function.
Code:
callq 0x7ffff3e1a1f8 <func_instance@plt>
Call a function, I think in a .so rather than in the current binary.
Code:
mov 0x8(%rsp),%rdx
Move a 64 bit quantity, probably from a local variable, into %rdx. Later code indicates that 64 bit quantity is a pointer.
Code:
mov %rax,%rsi
Make a copy (in %rsi) of the pointer returned by the previous function call.
Code:
movzbl 0x4f(%rax),%eax
cmp 0x4f(%rdx),%al
je 0x7ffff3e98fa0 <func_instance+496>
That is what an if statement compiles to. The original if would have been something equivalent to
if ( x->f != y->f )
where x is the struc pointer loaded earlier into %rdx from a local variable and y is the struct pointer returned by the function call and f is the char at offset 79 in the struct.

Last edited by johnsfine; 02-10-2012 at 09:13 AM.
 
Old 02-10-2012, 09:16 AM   #20
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,642
Blog Entries: 4

Rep: Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933
You are correct, thank you ... I replied on the original.

There are several reasons why such code can "fall down," and one of the very common reasons are differences in the so-called subroutine calling conventions that are being used. How does the caller supply arguments to the callee? This usually crops up when the code being called was compiled at a different time and perhaps by a different compiler, e.g. the target code is in a library of some kind. But, if the calls work anywhere in the application, this cannot be the problem.

Most of the time, if you find yourself diving down into assembly-language instructions, you are chasing a pointless red herring. The assembly code, whatever it may be, may be presumed to be "correct." The root cause of the problem must be chased down and understood, and it will inevitably be somewhere in your code but it probably is not terribly close to the point where the application fell off its log footbridge and landed face-down in the mud of the debugger.

I can count on the fingers of one hand the number of times when I successfully used a low-level debugger to usefully solve anything in application programming.
 
Old 02-10-2012, 10:04 AM   #21
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by sundialsvcs View Post
Most of the time, if you find yourself diving down into assembly-language instructions, you are chasing a pointless red herring.
In the current case, whatever bug caused that function to return a null pointer or whatever bug caused the calling code to not tolerate the return of a null pointer should have been easy to identify at the source level without diving into asm.

But...

Quote:
I can count on the fingers of one hand the number of times when I successfully used a low-level debugger to usefully solve anything in application programming.
I get called into each of the situations of impossible to debug by ordinary means that crop up in a moderate size group of programmers working on two extremely large complicated products. If it is difficult enough to call for my help at all, it is usually difficult enough to require looking at the asm code.

So I can count on the fingers of one hand the number of times this year (2012) that I successfully used asm level debugging to solve a problem in application programming that couldn't be solved otherwise. But it is still fairly early in the year. Longer term, it seems to happen less than once a week, but not a lot less.
 
Old 02-10-2012, 12:10 PM   #22
akshay_satish
Member
 
Registered: May 2011
Posts: 63

Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
Doesn't look similar to me. I think sundialsvcs answered on the original topic, so that doesn't help you. That's one of the risks of reopening an old thread for a new question.


It would be helpful to know the declaration of the function that was compiled/loaded as func_instance@plt
Based on the subsequent code, I expect that function was declared as returning a pointer to some struct type but when called, it returned a zero (NULL pointer). In x86_64 pointers are returned from functions in %rax
Code:
0x00007ffff3e98f1d <func_instance+365>:     movzbl 0x4f(%rax),%eax
That takes the character 79 beyond what is pointed to by %rax and moves it into %al (which is the low byte of %rax) and clears the remainder of %rax.
But you are reporting that it instead causes a NULL pointer dereference, so I assume %rax had zero in it before executing that instruction.


No. It is x86_64. IA64 is a different Intel 64 bit architecture.

Code:
jo 0x7ffff3e98f0f <func_instance+351>
Garbage (incorrect disassembly) caused by starting to disassemble at an address that wasn't an instruction boundary.
Code:
mov 0x10(%rsp),%rdi
Move a 64 bit quantity, probably from a local variable, into the register used to pass the first parameter to a function.
Code:
callq 0x7ffff3e1a1f8 <func_instance@plt>
Call a function, I think in a .so rather than in the current binary.
Code:
mov 0x8(%rsp),%rdx
Move a 64 bit quantity, probably from a local variable, into %rdx. Later code indicates that 64 bit quantity is a pointer.
Code:
mov %rax,%rsi
Make a copy (in %rsi) of the pointer returned by the previous function call.
Code:
movzbl 0x4f(%rax),%eax
cmp 0x4f(%rdx),%al
je 0x7ffff3e98fa0 <func_instance+496>
That is what an if statement compiles to. The original if would have been something equivalent to
if ( x->f != y->f )
where x is the struc pointer loaded earlier into %rdx from a local variable and y is the struct pointer returned by the function call and f is the char at offset 79 in the struct.
Thank you both of you for your valued suggestion. I am sorry for posting it here though.

yes rax had zero in it before executing the instruction;
Code:
movzbl 0x4f(%rax),%eax
Because when I executed;
[p/x $rax & p/x $rsi]
both of them returned 0.
basically the function called in callq has returned a NULL.
I shall paste the function code tomorrow and the formal parameter being passed to the function is an unsigned int(once i post the func, may be it will be clearer). Again, thank you for your brilliant thoughts.
 
Old 02-10-2012, 01:20 PM   #23
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by akshay_satish View Post
I shall paste the function code tomorrow and the formal parameter being passed to the function is an unsigned int
1) do you understand the difference between a "formal parameter" and an "actual parameter"?

2) If it is an unsigned int, why is it passed by copying a 64 bit local variable into a 64 bit register?

If the actual parameter were 64 bit and the formal parameter were unsigned int and the function were properly declared for the calling module, I think the compiler would have chosen a more efficient instruction to pass the parameter (but I'm not certain of that and the less efficient instruction should not be functionally incorrect).

Last edited by johnsfine; 02-10-2012 at 01:27 PM.
 
Old 02-13-2012, 04:38 AM   #24
akshay_satish
Member
 
Registered: May 2011
Posts: 63

Rep: Reputation: Disabled
The parameter passed to the function in callq is a const unsigned int. The function being called is the overloaded subscript operator

if (*(myRow[myCol[*loc].a]) == item)

"a" is a member of a structure. Looking at asm code, myCol[*loc].a is null(UINT_MAX). By dereferencing it with myRow it hit the SIGSEGV!
myCol[*loc].a should have had a valid value, it should not have returned UINT_MAX

typedef struct
{
unsigned char a;
}user;

user *myCol;

Last edited by akshay_satish; 02-13-2012 at 06:55 AM.
 
Old 02-13-2012, 08:07 AM   #25
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
I can't connect the small snips of C++ code in your post #24 to the small chunk of asm code in your post #17.

If you are correct about passing unsigned int, I guess the %rdi could be incorrect disassembly in post #17. If you started the disassembly a few instructions earlier, so misalignment problems are resolved before reaching the previous instruction, we could be sure.

You seem to be saying the function with the run time name func_instance@plt is an overloaded subscript operator returning a reference. Is that what you mean? If I understand you correctly, it is computing a reference to myCol[*loc] and that reference is an invalid pointer.

But I don't follow what you are saying about UINT_MAX and especially not what you are saying about myCol[*loc].a. That is a character. You seem to be saying its value is invalid, but if that is related to the asm code you posted, it is the address myCol[*loc] that is invalid, not the value myCol[*loc].a.

Last edited by johnsfine; 02-13-2012 at 08:10 AM.
 
Old 02-13-2012, 08:16 AM   #26
akshay_satish
Member
 
Registered: May 2011
Posts: 63

Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
I can't connect the small snips of C++ code in your post #24 to the small chunk of asm code in your post #17.

If you are correct about passing unsigned int, I guess the %rdi could be incorrect disassembly in post #17. If you started the disassembly a few instructions earlier, so misalignment problems are resolved before reaching the previous instruction, we could be sure.

You seem to be saying the function with the run time name func_instance@plt is an overloaded subscript operator returning a reference. Is that what you mean? If I understand you correctly, it is computing a reference to myCol[*loc] and that reference is an invalid pointer.

But I don't follow what you are saying about UINT_MAX and especially not what you are saying about myCol[*loc].a. That is a character. You seem to be saying its value is invalid, but if that is related to the asm code you posted, it is the address myCol[*loc] that is invalid, not the value myCol[*loc].a.
I am so SORRY. a is not a char!

typedef struct
{
unsigned int a;
}user;

the overloaded [] operator, it basically returns pointer to object stored at the index passed as a parameter.
So what i was trying to say was;
myCol[*loc].a was NULL when dereferenced caused the SEGV.
 
Old 02-13-2012, 08:36 AM   #27
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
That makes it even harder to see a connection with the disassembly you posted before.

I think the disassembly you posted before is a different if statement than the one you are looking at now.

I assume the disassembly correctly represents the point of the seg fault, so I think you are looking in the wrong place in the source code for that seg fault.

How big is func_instance ? If you post the whole source code to func_instance, I might be able to estimate the correct point of the seq fault.

Last edited by johnsfine; 02-13-2012 at 08:43 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Beginner question for C/Assembly p4nk4j Programming 5 05-18-2007 08:43 PM
Assembly Question aceman817 Programming 1 02-28-2006 01:01 AM
MIPS assembly question Gnute Programming 1 08-24-2004 05:33 PM
C & Assembly question eantoranz Programming 3 04-23-2004 01:18 PM
Assembly Question! wwnn1 Programming 4 06-16-2002 01:18 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:15 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration