Re[2]: argv



Hi John,

The C code for main(int argc, char *argv[]) is standardized and can only mean
one thing on a 32-bit version of any program: argc is an immediate value of 4
bytes length and argv is a 4-byte pointer to an array of 32-pointers to
zero-terminated strings. Then when main is called, it will first push the
32-bit argv integer value, then push a 32-bit argc pointer, then push the
32-bit return address. So the offsets are correct, i.e. -- [ebp-0] = return
address of callee, [ebp-4] = int argc, and [ebp-8] = *argv.

So debugging this is easy: look at the first three 32-bit items on the stack
at the entry point of main(), and look for an integer value of 4 (because I
have three test parameters on the command line that I am passing) on the
stack. But it does not exist *anywhere* on the stack, even 20 or 30 items
down. But then the API documentation for GTK+ says that argc is not an int,
but a pointer to an int (int *argc and char ***argv). So if I presume
everything on the stack is a pointer, I still cannot find the integer value of
4. The closest I have come is a value of 2, which is still wrong. I don't know
if I mentioned this, but *every* value on the stack points to nonsense
(meaning "not the command line or it's address"), no matter how far you
recurse into it. The address where the command line string is contained is not
even close to being referenced by anything on the stack. It's interesting that
my debugger can automatically find the command line but GTK+ cannot.

Therefore it would make sense that the code you have posted below does not
work due to the above mentioned observations, although according to the
documentation it seems as though it should ... unless the API documentation is
wrong or my 32-bit GTK+ runtimes I got from the GtkD project are corrupted
with bad source code or that GtkD used a compiler parameter that restricts the
runtimes to processing of the GUI only. So I did a little research and
discovered that there is a function for getting the command line in GTK+:

        g_application_new(G_APPLICATION_HANDLES_COMMAND_LINE)

which used in conjunction with g_signal_connect() and G_CALLBACK, passes it
off to a function where you can use the code like you posted below, with the
usual expected results. Why have this function though, if a simple direct
routine like you posted below would work? It would be overkill, but I am going
to try using this method and if it works, it would prove that the GTK+ API
documentation is incorrect, that argc and argv are not pointers or values, but
handles -- at least in the 32-bit version of GTK+ for Windows. This would
explain why I can't make it work in GTK+ v3.18 or why the code posted below
doesn't work.

Andrew

On 4/14/2016 at 8:03 AM, John Coppens <john jcoppens com> wrote:
On Sat, 9 Apr 2016 18:39:49 -0700
"Andrew Robinson" <arobinson18 cox net> wrote:

The problem is that [ebp + 12] and [ebp + 8] point to nonsense. I ran a
debugger and looked at the stack, and there is nothing else on the stack
except for ebp, rtn addr, and these two parameters. I even tried
daisy-chaining the addresses to see where they would lead, and they are not
even close to pointing to the actual command line. I can easily find the
command line using a memory search, so I know what address it should be.
What
am I doing wrong here? I have:

Never done this, and I don't have Windows, so I don't know if this is useful.

- The command line you found may not be the same as is passed to main().
Recall that that argv is an array of strings, not pointers to the actual
command line.

- This program shows the addresses of the individual args:

#include <stdio.h>                                                           
          
  
int
main(int argc, char *argv[]) {
 int i;

 for (i = 0; i < argc; i++) {
   printf("%p: %s\n", &argv[i], argv[i]);
 }

 return 0;
}

~$ ./args a b c d    
0x7ffd48ffc538: ./args
0x7ffd48ffc540: a
0x7ffd48ffc548: b
0x7ffd48ffc550: c
0x7ffd48ffc558: d

As you can see, the addresses are aligned to 8 byte levels, as this is a
64-bit computer. Your offsets could be wrong, as they depend on the
word length of the computer.

John



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]