What surprises me is that this core dump file is as big as the one generated by debug version app and has size of 1.6G bytes!
You shouldn't be surprised by that. The core dump contains modifiable segments of the application memory. The application compiled with debug info will have exactly the same modifiable memory as the application compiled without debug info, and should produce exactly the same core dump (assuming other compilation flags are the same, and that the application is repeatable from run to run).
The debug info is needed to make sense of that memory dump in the debugger. But you can also make sense of that memory dump without debug info, it's just much more manual and tedious.
Is there anyway to get more information including the call stack?
You said you already have the call stack.
The best practice is to always build your application with full debug info, e.g.
gcc -O2 -g -c foo.cc -o foo.o
gcc -g foo.o bar.o ... -o app
Then keep the resulting (large) binary for debugging, but ship a stripped variant of that binary to end-users:
cp app app-stripped
strip -g app-stripped # removes all debug info from app-stripped
Now when you get a core dump from app-stripped, use the full-debug app
to analyze that core.
Alternatively, you can use separate debuginfo files, as documented here.