For copying, use ddrescue, safecopy, or dd_rescue. They all keep a log of failed areas, as well as automatically retry until they can get the data out.
The general usage is:
ddrescue: (don't mix up with the older dd_rescue)
ddrescue /dev/sdc3 sdc3.img sdc3.map
If wanted, repeat with --retrim or `--try-again:
ddrescue --try-again /dev/sdc3 sdc3.img sdc3.map
Don't forget to specify the mapfile to record bad areas in.
safecopy:
safecopy --stage1 /dev/sdc3 sdc3.img
safecopy --stage2 /dev/sdc3 sdc3.img
safecopy --stage3 /dev/sdc3 sdc3.img
After stage 3, you'll have a stage3.badblocks file listing the individual bad sectors.
If you want to retry, use:
mv stage3.badblocks stage2.badblocks
safecopy --stage3 /dev/sdc3 sdc3.img
dd_rescue: (not to be confused with the more-capable ddrescue)
dd_rescue -o sdc3.badblocks /dev/sd3 sdc3.img
(I've no idea if this tool supports resuming/retrying with a 2nd invocation, but at least it does output a badblocks log.)
These programs emphasize getting as much data out fast as they can, and keeping the slow recovery for later. So don't be surprised if "stage 1" will skip whole megabytes just because of a single bad block – it'll return to that in stage 2.
For emulating a bad disk, take the badblocks log you just got, and apply it to this post:
Use dmsetup to create a device backed by the "error" target. It will show up in /dev/mapper/<name>.
Page 7 of the Device mapper presentation (PDF) has exactly what you're looking for:
dmsetup create bad_disk << EOF
0 8 linear /dev/sdb1 0
8 1 error
9 204791 linear /dev/sdb1 9
EOF
Or leave out the sdb1 parts to and put the "error" target as the device for blocks 0 - 8 (instead of sdb1) to make a pure error disk.
See also The Device Mapper appendix from "RHEL 5
Logical Volume Manager Administration".
— Peter Cordes, https://stackoverflow.com/questions/1870696/simulate-a-faulty-block-device-with-read-errors
(Converting a badblocks log or a ddrescue mapfile to dmsetup table syntax is left as an exercise to the reader...)